mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-12-22 17:27:38 +00:00
Merge branch 'IntellectualSites:main' into main
This commit is contained in:
commit
eb204998e9
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.
|
description: Which server version version you using? If your server version is not listed, it is not supported. Update to a supported version first.
|
||||||
multiple: false
|
multiple: false
|
||||||
options:
|
options:
|
||||||
- '1.20.4'
|
- '1.20.5/6'
|
||||||
- '1.20'
|
- '1.20'
|
||||||
- '1.19.4'
|
- '1.19.4'
|
||||||
- '1.18.2'
|
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
|
2
.github/workflows/build-pr.yml
vendored
2
.github/workflows/build-pr.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
cache: gradle
|
cache: gradle
|
||||||
java-version: 17
|
java-version: 21
|
||||||
- name: Build on ${{ matrix.os }}
|
- name: Build on ${{ matrix.os }}
|
||||||
run: ./gradlew build -s
|
run: ./gradlew build -s
|
||||||
- name: Archive artifacts
|
- name: Archive artifacts
|
||||||
|
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
cache: gradle
|
cache: gradle
|
||||||
java-version: 17
|
java-version: 21
|
||||||
- name: Clean Build
|
- name: Clean Build
|
||||||
run: ./gradlew clean build --no-daemon
|
run: ./gradlew clean build --no-daemon
|
||||||
- name: Determine release status
|
- name: Determine release status
|
||||||
|
2
.github/workflows/codeql.yml
vendored
2
.github/workflows/codeql.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
cache: gradle
|
cache: gradle
|
||||||
java-version: 17
|
java-version: 21
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v3
|
uses: github/codeql-action/init@v3
|
||||||
with:
|
with:
|
||||||
|
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
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Label conflicting PRs
|
- name: Label conflicting PRs
|
||||||
uses: eps1lon/actions-label-merge-conflict@v3.0.0
|
uses: eps1lon/actions-label-merge-conflict@v3.0.1
|
||||||
with:
|
with:
|
||||||
dirtyLabel: "unresolved-merge-conflict"
|
dirtyLabel: "unresolved-merge-conflict"
|
||||||
repoToken: "${{ secrets.GITHUB_TOKEN }}"
|
repoToken: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
2
.github/workflows/upload-release-assets.yml
vendored
2
.github/workflows/upload-release-assets.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
cache: gradle
|
cache: gradle
|
||||||
java-version: 17
|
java-version: 21
|
||||||
- name: Clean Build
|
- name: Clean Build
|
||||||
run: ./gradlew clean build --no-daemon
|
run: ./gradlew clean build --no-daemon
|
||||||
- name: Upload Release Assets
|
- name: Upload Release Assets
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
= Compiling
|
= Compiling
|
||||||
|
|
||||||
You can compile FastAsyncWorldEdit as long as you have some version of Java greater than or equal to 17 installed. Gradle will download JDK 17 specifically if needed,
|
You can compile FastAsyncWorldEdit as long as you have some version of Java greater than or equal to 21 installed. Gradle will download JDK 21 specifically if needed,
|
||||||
but it needs some version of Java to bootstrap from.
|
but it needs some version of Java to bootstrap from.
|
||||||
|
|
||||||
Note that if you have JRE 8 installed, Gradle will currently attempt to use that to compile, which will not work. It is easiest to uninstall JRE 8 and replace it with JDK 17.
|
Note that if you have JRE 8 installed, Gradle will currently attempt to use that to compile, which will not work. It is easiest to uninstall JRE 8 and replace it with JDK 21.
|
||||||
|
|
||||||
You can get the JDK 17 link:https://adoptium.net/[here] from Adoptium.
|
You can get the JDK 21 link:https://adoptium.net/[here] from Adoptium.
|
||||||
|
|
||||||
The build process uses Gradle, which you do *not* need to download. FastAsyncWorldEdit is a multi-module project with three active modules:
|
The build process uses Gradle, which you do *not* need to download. FastAsyncWorldEdit is a multi-module project with three active modules:
|
||||||
|
|
||||||
|
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@ -7,7 +7,7 @@ pipeline {
|
|||||||
stage('Build') {
|
stage('Build') {
|
||||||
steps {
|
steps {
|
||||||
withEnv([
|
withEnv([
|
||||||
"PATH+JAVA=${tool 'Temurin-17.0.7_7'}/bin"
|
"PATH+JAVA=${tool 'Temurin-21.0.3_9'}/bin"
|
||||||
]) {
|
]) {
|
||||||
sh './gradlew clean build'
|
sh './gradlew clean build'
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import xyz.jpenilla.runpaper.task.RunServer
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("io.github.gradle-nexus.publish-plugin") version "2.0.0"
|
id("io.github.gradle-nexus.publish-plugin") version "2.0.0"
|
||||||
id("xyz.jpenilla.run-paper") version "2.2.3"
|
id("xyz.jpenilla.run-paper") version "2.3.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!File("$rootDir/.git").exists()) {
|
if (!File("$rootDir/.git").exists()) {
|
||||||
@ -34,7 +34,7 @@ logger.lifecycle("""
|
|||||||
*******************************************
|
*******************************************
|
||||||
""")
|
""")
|
||||||
|
|
||||||
var rootVersion by extra("2.9.3")
|
var rootVersion by extra("2.10.1")
|
||||||
var snapshot by extra("SNAPSHOT")
|
var snapshot by extra("SNAPSHOT")
|
||||||
var revision: String by extra("")
|
var revision: String by extra("")
|
||||||
var buildNumber by extra("")
|
var buildNumber by extra("")
|
||||||
@ -83,7 +83,7 @@ allprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
applyCommonConfiguration()
|
applyCommonConfiguration()
|
||||||
val supportedVersions = listOf("1.18.2", "1.19.4", "1.20", "1.20.4")
|
val supportedVersions = listOf("1.19.4", "1.20", "1.20.4", "1.20.5", "1.20.6")
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
supportedVersions.forEach {
|
supportedVersions.forEach {
|
||||||
|
@ -28,11 +28,23 @@ dependencies {
|
|||||||
implementation(gradleApi())
|
implementation(gradleApi())
|
||||||
implementation("org.ajoberstar.grgit:grgit-gradle:5.2.2")
|
implementation("org.ajoberstar.grgit:grgit-gradle:5.2.2")
|
||||||
implementation("com.github.johnrengelman:shadow:8.1.1")
|
implementation("com.github.johnrengelman:shadow:8.1.1")
|
||||||
implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.5.15")
|
implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.7.1")
|
||||||
|
constraints {
|
||||||
|
val asmVersion = "[9.7,)"
|
||||||
|
implementation("org.ow2.asm:asm:$asmVersion") {
|
||||||
|
because("Need Java 21 support in shadow")
|
||||||
|
}
|
||||||
|
implementation("org.ow2.asm:asm-commons:$asmVersion") {
|
||||||
|
because("Need Java 21 support in shadow")
|
||||||
|
}
|
||||||
|
implementation("org.vafer:jdependency:[2.10,)") {
|
||||||
|
because("Need Java 21 support in shadow")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
jvmToolchain {
|
jvmToolchain {
|
||||||
(this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(17))
|
(this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(21))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ fun Project.applyCommonConfiguration() {
|
|||||||
|
|
||||||
plugins.withId("java") {
|
plugins.withId("java") {
|
||||||
the<JavaPluginExtension>().toolchain {
|
the<JavaPluginExtension>().toolchain {
|
||||||
languageVersion.set(JavaLanguageVersion.of(17))
|
languageVersion.set(JavaLanguageVersion.of(21))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean
|
|||||||
.matching { it.name == "compileJava" || it.name == "compileTestJava" }
|
.matching { it.name == "compileJava" || it.name == "compileTestJava" }
|
||||||
.configureEach {
|
.configureEach {
|
||||||
val disabledLint = listOf(
|
val disabledLint = listOf(
|
||||||
"processing", "path", "fallthrough", "serial"
|
"processing", "path", "fallthrough", "serial", "overloads", "this-escape",
|
||||||
)
|
)
|
||||||
options.release.set(17)
|
options.release.set(17)
|
||||||
options.compilerArgs.addAll(listOf("-Xlint:all") + disabledLint.map { "-Xlint:-$it" })
|
options.compilerArgs.addAll(listOf("-Xlint:all") + disabledLint.map { "-Xlint:-$it" })
|
||||||
@ -31,7 +31,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean
|
|||||||
}
|
}
|
||||||
|
|
||||||
configurations.all {
|
configurations.all {
|
||||||
attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17)
|
attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<Test>().configureEach {
|
tasks.withType<Test>().configureEach {
|
||||||
@ -61,7 +61,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean
|
|||||||
"https://jd.advntr.dev/api/latest/",
|
"https://jd.advntr.dev/api/latest/",
|
||||||
"https://logging.apache.org/log4j/2.x/javadoc/log4j-api/",
|
"https://logging.apache.org/log4j/2.x/javadoc/log4j-api/",
|
||||||
"https://www.antlr.org/api/Java/",
|
"https://www.antlr.org/api/Java/",
|
||||||
"https://jd.papermc.io/paper/1.20/",
|
"https://jd.papermc.io/paper/1.20.6/",
|
||||||
"https://intellectualsites.github.io/fastasyncworldedit-javadocs/worldedit-core/"
|
"https://intellectualsites.github.io/fastasyncworldedit-javadocs/worldedit-core/"
|
||||||
)
|
)
|
||||||
docTitle = "${rootProject.name}-${project.description}" + " " + "${rootProject.version}"
|
docTitle = "${rootProject.name}-${project.description}" + " " + "${rootProject.version}"
|
||||||
|
@ -122,7 +122,7 @@ fun Project.applyLibrariesConfiguration() {
|
|||||||
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
|
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
|
||||||
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
||||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
|
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
|
||||||
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17)
|
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21)
|
||||||
}
|
}
|
||||||
outgoing.artifact(tasks.named("jar"))
|
outgoing.artifact(tasks.named("jar"))
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ fun Project.applyLibrariesConfiguration() {
|
|||||||
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
|
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
|
||||||
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
||||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
|
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
|
||||||
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17)
|
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21)
|
||||||
}
|
}
|
||||||
outgoing.artifact(tasks.named("jar"))
|
outgoing.artifact(tasks.named("jar"))
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[versions]
|
[versions]
|
||||||
# Minecraft expectations
|
# Minecraft expectations
|
||||||
paper = "1.20.4-R0.1-SNAPSHOT"
|
paper = "1.20.6-R0.1-SNAPSHOT"
|
||||||
fastutil = "8.5.9"
|
fastutil = "8.5.9"
|
||||||
guava = "31.1-jre"
|
guava = "31.1-jre"
|
||||||
log4j = "2.19.0"
|
log4j = "2.19.0"
|
||||||
@ -9,25 +9,25 @@ snakeyaml = "2.0"
|
|||||||
|
|
||||||
# Plugins
|
# Plugins
|
||||||
dummypermscompat = "1.10"
|
dummypermscompat = "1.10"
|
||||||
worldguard-bukkit = "7.0.9"
|
worldguard-bukkit = "7.0.10"
|
||||||
mapmanager = "1.8.0-SNAPSHOT"
|
mapmanager = "1.8.0-SNAPSHOT"
|
||||||
griefprevention = "17.0.0"
|
griefprevention = "17.0.0"
|
||||||
griefdefender = "2.1.0-SNAPSHOT"
|
griefdefender = "2.1.0-SNAPSHOT"
|
||||||
residence = "4.5._13.1"
|
residence = "4.5._13.1"
|
||||||
towny = "0.100.2.3"
|
towny = "0.100.2.9"
|
||||||
plotsquared = "7.3.8"
|
plotsquared = "7.3.8"
|
||||||
|
|
||||||
# Third party
|
# Third party
|
||||||
bstats = "3.0.2"
|
bstats = "3.0.2"
|
||||||
sparsebitset = "1.3"
|
sparsebitset = "1.3"
|
||||||
parallelgzip = "1.0.5"
|
parallelgzip = "1.0.5"
|
||||||
adventure = "4.16.0"
|
adventure = "4.17.0"
|
||||||
adventure-bukkit = "4.3.2"
|
adventure-bukkit = "4.3.2"
|
||||||
checkerqual = "3.42.0"
|
checkerqual = "3.43.0"
|
||||||
truezip = "6.8.4"
|
truezip = "6.8.4"
|
||||||
auto-value = "1.10.4"
|
auto-value = "1.10.4"
|
||||||
findbugs = "3.0.2"
|
findbugs = "3.0.2"
|
||||||
rhino-runtime = "1.7.14"
|
rhino-runtime = "1.7.15"
|
||||||
zstd-jni = "1.4.8-1" # Not latest as it can be difficult to obtain latest ZSTD libs
|
zstd-jni = "1.4.8-1" # Not latest as it can be difficult to obtain latest ZSTD libs
|
||||||
antlr4 = "4.13.1"
|
antlr4 = "4.13.1"
|
||||||
json-simple = "1.1.1"
|
json-simple = "1.1.1"
|
||||||
@ -35,7 +35,7 @@ jlibnoise = "1.0.0"
|
|||||||
jchronic = "0.2.4a"
|
jchronic = "0.2.4a"
|
||||||
lz4-java = "1.8.0"
|
lz4-java = "1.8.0"
|
||||||
lz4-stream = "1.0.0"
|
lz4-stream = "1.0.0"
|
||||||
commons-cli = "1.6.0"
|
commons-cli = "1.7.0"
|
||||||
paperlib = "1.0.8"
|
paperlib = "1.0.8"
|
||||||
paster = "1.1.6"
|
paster = "1.1.6"
|
||||||
vault = "1.7.1"
|
vault = "1.7.1"
|
||||||
@ -46,7 +46,7 @@ text = "3.0.4"
|
|||||||
piston = "0.5.10"
|
piston = "0.5.10"
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
mockito = "5.11.0"
|
mockito = "5.12.0"
|
||||||
|
|
||||||
# Gradle plugins
|
# Gradle plugins
|
||||||
pluginyml = "0.6.0"
|
pluginyml = "0.6.0"
|
||||||
|
@ -2,7 +2,7 @@ rootProject.name = "FastAsyncWorldEdit"
|
|||||||
|
|
||||||
include("worldedit-libs")
|
include("worldedit-libs")
|
||||||
|
|
||||||
listOf("1_18_2", "1_19_4", "1_20", "1_20_2", "1_20_4").forEach {
|
listOf("1_19_4", "1_20", "1_20_2", "1_20_4", "1_20_5").forEach {
|
||||||
include("worldedit-bukkit:adapters:adapter-$it")
|
include("worldedit-bukkit:adapters:adapter-$it")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,6 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT
|
// url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT
|
||||||
the<PaperweightUserDependenciesExtension>().paperDevBundle("1.20.4-R0.1-20240420.200855-173")
|
the<PaperweightUserDependenciesExtension>().paperDevBundle("1.20.4-R0.1-20240424.165410-174")
|
||||||
compileOnly(libs.paperlib)
|
compileOnly(libs.paperlib)
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,6 @@ import net.minecraft.world.level.entity.PersistentEntitySectionManager;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.craftbukkit.v1_20_R3.CraftChunk;
|
import org.bukkit.craftbukkit.v1_20_R3.CraftChunk;
|
||||||
import sun.misc.Unsafe;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
@ -11,7 +11,7 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.18.2-R0.1-SNAPSHOT
|
// url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.6-R0.1-SNAPSHOT/
|
||||||
the<PaperweightUserDependenciesExtension>().paperDevBundle("1.18.2-R0.1-20220920.010157-167")
|
the<PaperweightUserDependenciesExtension>().paperDevBundle("1.20.6-R0.1-20240520.005421-60")
|
||||||
compileOnly(libs.paperlib)
|
compileOnly(libs.paperlib)
|
||||||
}
|
}
|
@ -17,24 +17,23 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R2;
|
package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4;
|
||||||
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.mojang.datafixers.util.Either;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.Lifecycle;
|
import com.mojang.serialization.Lifecycle;
|
||||||
|
import com.sk89q.jnbt.NBTConstants;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.blocks.BaseItem;
|
import com.sk89q.worldedit.blocks.BaseItem;
|
||||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.PaperweightPlatformAdapter;
|
|
||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
import com.sk89q.worldedit.extension.platform.Watchdog;
|
import com.sk89q.worldedit.extension.platform.Watchdog;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
@ -81,14 +80,20 @@ import com.sk89q.worldedit.world.block.BlockTypes;
|
|||||||
import com.sk89q.worldedit.world.item.ItemType;
|
import com.sk89q.worldedit.world.item.ItemType;
|
||||||
import net.minecraft.Util;
|
import net.minecraft.Util;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
|
import net.minecraft.core.component.DataComponentPatch;
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.nbt.NbtOps;
|
||||||
|
import net.minecraft.nbt.Tag;
|
||||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||||
import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
|
import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.dedicated.DedicatedServer;
|
import net.minecraft.server.dedicated.DedicatedServer;
|
||||||
import net.minecraft.server.level.ChunkHolder;
|
import net.minecraft.server.level.ChunkResult;
|
||||||
import net.minecraft.server.level.ServerChunkCache;
|
import net.minecraft.server.level.ServerChunkCache;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||||
@ -112,10 +117,10 @@ import net.minecraft.world.level.block.entity.StructureBlockEntity;
|
|||||||
import net.minecraft.world.level.block.state.StateDefinition;
|
import net.minecraft.world.level.block.state.StateDefinition;
|
||||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
import net.minecraft.world.level.dimension.LevelStem;
|
import net.minecraft.world.level.dimension.LevelStem;
|
||||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
import net.minecraft.world.level.levelgen.WorldOptions;
|
||||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||||
import net.minecraft.world.level.storage.PrimaryLevelData;
|
import net.minecraft.world.level.storage.PrimaryLevelData;
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
@ -124,13 +129,13 @@ import org.bukkit.Bukkit;
|
|||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World.Environment;
|
import org.bukkit.World.Environment;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftServer;
|
import org.bukkit.craftbukkit.CraftServer;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
import org.bukkit.craftbukkit.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData;
|
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity;
|
import org.bukkit.craftbukkit.entity.CraftEntity;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.util.CraftMagicNumbers;
|
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
@ -155,7 +160,6 @@ import java.util.Set;
|
|||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ForkJoinPool;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -166,33 +170,28 @@ import static com.google.common.base.Preconditions.checkState;
|
|||||||
|
|
||||||
public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft.nbt.Tag> {
|
public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft.nbt.Tag> {
|
||||||
|
|
||||||
private static final Set<SideEffect> SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet(
|
private static final Codec<DataComponentPatch> COMPONENTS_CODEC = DataComponentPatch.CODEC.optionalFieldOf(
|
||||||
SideEffect.NEIGHBORS,
|
"components", DataComponentPatch.EMPTY
|
||||||
SideEffect.LIGHTING,
|
).codec();
|
||||||
SideEffect.VALIDATION,
|
|
||||||
SideEffect.ENTITY_AI,
|
private final Logger logger = Logger.getLogger(getClass().getCanonicalName());
|
||||||
SideEffect.EVENTS,
|
|
||||||
SideEffect.UPDATE
|
|
||||||
);
|
|
||||||
private final Field serverWorldsField;
|
private final Field serverWorldsField;
|
||||||
private final Method getChunkFutureMethod;
|
private final Method getChunkFutureMethod;
|
||||||
private final Field chunkProviderExecutorField;
|
private final Field chunkProviderExecutorField;
|
||||||
private final Logger LOGGER = Logger.getLogger(getClass().getCanonicalName());
|
private final Watchdog watchdog;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Code that may break between versions of Minecraft
|
// Code that may break between versions of Minecraft
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
private final Watchdog watchdog;
|
|
||||||
private final LoadingCache<ServerLevel, PaperweightFakePlayer> fakePlayers
|
|
||||||
= CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new));
|
|
||||||
|
|
||||||
public PaperweightAdapter() throws NoSuchFieldException, NoSuchMethodException {
|
public PaperweightAdapter() throws NoSuchFieldException, NoSuchMethodException {
|
||||||
// A simple test
|
// A simple test
|
||||||
CraftServer.class.cast(Bukkit.getServer());
|
CraftServer.class.cast(Bukkit.getServer());
|
||||||
|
|
||||||
int dataVersion = CraftMagicNumbers.INSTANCE.getDataVersion();
|
int dataVersion = CraftMagicNumbers.INSTANCE.getDataVersion();
|
||||||
if (dataVersion != 2975) {
|
if (dataVersion != 3837 && dataVersion != 3839) {
|
||||||
throw new UnsupportedClassVersionError("Not 1.18.2!");
|
throw new UnsupportedClassVersionError("Not 1.20.(5/6)!");
|
||||||
}
|
}
|
||||||
|
|
||||||
serverWorldsField = CraftServer.class.getDeclaredField("worlds");
|
serverWorldsField = CraftServer.class.getDeclaredField("worlds");
|
||||||
@ -209,7 +208,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
);
|
);
|
||||||
chunkProviderExecutorField.setAccessible(true);
|
chunkProviderExecutorField.setAccessible(true);
|
||||||
|
|
||||||
new PaperweightDataConverters(CraftMagicNumbers.INSTANCE.getDataVersion(), this).build(ForkJoinPool.commonPool());
|
new PaperweightDataConverters(CraftMagicNumbers.INSTANCE.getDataVersion(), this).buildUnoptimized();
|
||||||
|
|
||||||
Watchdog watchdog;
|
Watchdog watchdog;
|
||||||
try {
|
try {
|
||||||
@ -231,6 +230,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataFixer getDataFixer() {
|
||||||
|
return PaperweightDataConverters.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the given NBT data into the given tile entity.
|
* Read the given NBT data into the given tile entity.
|
||||||
*
|
*
|
||||||
@ -238,7 +242,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
* @param tag the tag
|
* @param tag the tag
|
||||||
*/
|
*/
|
||||||
static void readTagIntoTileEntity(net.minecraft.nbt.CompoundTag tag, BlockEntity tileEntity) {
|
static void readTagIntoTileEntity(net.minecraft.nbt.CompoundTag tag, BlockEntity tileEntity) {
|
||||||
tileEntity.load(tag);
|
tileEntity.loadWithComponents(tag, MinecraftServer.getServer().registryAccess());
|
||||||
tileEntity.setChanged();
|
tileEntity.setChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,9 +275,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
* @param tag the tag
|
* @param tag the tag
|
||||||
*/
|
*/
|
||||||
private static void readTagIntoEntity(net.minecraft.nbt.CompoundTag tag, Entity entity) {
|
private static void readTagIntoEntity(net.minecraft.nbt.CompoundTag tag, Entity entity) {
|
||||||
//FAWE start - avoid villager async catcher
|
entity.load(tag);
|
||||||
PaperweightPlatformAdapter.readEntityIntoTag(entity, tag);
|
|
||||||
//FAWE end
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -287,34 +289,14 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Block getBlockFromType(BlockType blockType) {
|
private static Block getBlockFromType(BlockType blockType) {
|
||||||
return Registry.BLOCK.get(ResourceLocation.tryParse(blockType.getId()));
|
|
||||||
|
return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.BLOCK).get(ResourceLocation.tryParse(
|
||||||
|
blockType.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Item getItemFromType(ItemType itemType) {
|
private static Item getItemFromType(ItemType itemType) {
|
||||||
return Registry.ITEM.get(ResourceLocation.tryParse(itemType.getId()));
|
return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(
|
||||||
}
|
itemType.getId()));
|
||||||
|
|
||||||
private static net.minecraft.core.Direction adapt(Direction face) {
|
|
||||||
switch (face) {
|
|
||||||
case NORTH:
|
|
||||||
return net.minecraft.core.Direction.NORTH;
|
|
||||||
case SOUTH:
|
|
||||||
return net.minecraft.core.Direction.SOUTH;
|
|
||||||
case WEST:
|
|
||||||
return net.minecraft.core.Direction.WEST;
|
|
||||||
case EAST:
|
|
||||||
return net.minecraft.core.Direction.EAST;
|
|
||||||
case DOWN:
|
|
||||||
return net.minecraft.core.Direction.DOWN;
|
|
||||||
case UP:
|
|
||||||
default:
|
|
||||||
return net.minecraft.core.Direction.UP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataFixer getDataFixer() {
|
|
||||||
return PaperweightDataConverters.INSTANCE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -334,6 +316,25 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
return combinedId == 0 && state.getBlockType() != BlockTypes.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId);
|
return combinedId == 0 && state.getBlockType() != BlockTypes.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) {
|
||||||
|
int internalId = Block.getId(blockState);
|
||||||
|
BlockState state = BlockStateIdAccess.getBlockStateById(internalId);
|
||||||
|
if (state == null) {
|
||||||
|
state = BukkitAdapter.adapt(CraftBlockData.createData(blockState));
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BiomeType adapt(Biome biome) {
|
||||||
|
var mcBiome = ((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registries.BIOME).getKey(
|
||||||
|
biome);
|
||||||
|
if (mcBiome == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return BiomeType.REGISTRY.get(mcBiome.toString());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlock(Location location) {
|
public BlockState getBlock(Location location) {
|
||||||
checkNotNull(location);
|
checkNotNull(location);
|
||||||
@ -373,21 +374,37 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
// Read the NBT data
|
// Read the NBT data
|
||||||
BlockEntity te = chunk.getBlockEntity(blockPos);
|
BlockEntity te = chunk.getBlockEntity(blockPos);
|
||||||
if (te != null) {
|
if (te != null) {
|
||||||
net.minecraft.nbt.CompoundTag tag = te.saveWithId();
|
net.minecraft.nbt.CompoundTag tag = te.saveWithId(MinecraftServer.getServer().registryAccess());
|
||||||
//FAWE start - BinaryTag
|
|
||||||
return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag));
|
return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag));
|
||||||
//FAWE end
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return state.toBaseBlock();
|
return state.toBaseBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final HashMap<BiomeType, Holder<Biome>> biomeTypeToNMSCache = new HashMap<>();
|
||||||
|
private static final HashMap<Holder<Biome>, BiomeType> biomeTypeFromNMSCache = new HashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) {
|
public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) {
|
||||||
return new PaperweightWorldNativeAccess(
|
return new PaperweightWorldNativeAccess(this, new WeakReference<>(((CraftWorld) world).getHandle()));
|
||||||
this,
|
}
|
||||||
new WeakReference<>(((CraftWorld) world).getHandle())
|
|
||||||
);
|
private static net.minecraft.core.Direction adapt(Direction face) {
|
||||||
|
switch (face) {
|
||||||
|
case NORTH:
|
||||||
|
return net.minecraft.core.Direction.NORTH;
|
||||||
|
case SOUTH:
|
||||||
|
return net.minecraft.core.Direction.SOUTH;
|
||||||
|
case WEST:
|
||||||
|
return net.minecraft.core.Direction.WEST;
|
||||||
|
case EAST:
|
||||||
|
return net.minecraft.core.Direction.EAST;
|
||||||
|
case DOWN:
|
||||||
|
return net.minecraft.core.Direction.DOWN;
|
||||||
|
case UP:
|
||||||
|
default:
|
||||||
|
return net.minecraft.core.Direction.UP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
@ -429,16 +446,19 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
CraftEntity craftEntity = ((CraftEntity) entity);
|
CraftEntity craftEntity = ((CraftEntity) entity);
|
||||||
Entity mcEntity = craftEntity.getHandle();
|
Entity mcEntity = craftEntity.getHandle();
|
||||||
|
|
||||||
|
// Do not allow creating of passenger entity snapshots, passengers are included in the vehicle entity
|
||||||
|
if (mcEntity.isPassenger()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
String id = getEntityId(mcEntity);
|
String id = getEntityId(mcEntity);
|
||||||
|
|
||||||
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
|
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
|
||||||
readEntityIntoTag(mcEntity, tag);
|
readEntityIntoTag(mcEntity, tag);
|
||||||
//FAWE start - CompoundBinaryTag
|
|
||||||
return new BaseEntity(
|
return new BaseEntity(
|
||||||
com.sk89q.worldedit.world.entity.EntityTypes.get(id),
|
com.sk89q.worldedit.world.entity.EntityTypes.get(id),
|
||||||
LazyReference.from(() -> (CompoundBinaryTag) toNativeBinary(tag))
|
LazyReference.from(() -> (CompoundBinaryTag) toNativeBinary(tag))
|
||||||
);
|
);
|
||||||
//FAWE end
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -471,6 +491,22 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This removes all unwanted tags from the main entity and all its passengers
|
||||||
|
private void removeUnwantedEntityTagsRecursively(net.minecraft.nbt.CompoundTag tag) {
|
||||||
|
for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
|
||||||
|
tag.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adapted from net.minecraft.world.entity.EntityType#loadEntityRecursive
|
||||||
|
if (tag.contains("Passengers", NBTConstants.TYPE_LIST)) {
|
||||||
|
net.minecraft.nbt.ListTag nbttaglist = tag.getList("Passengers", NBTConstants.TYPE_COMPOUND);
|
||||||
|
|
||||||
|
for (int i = 0; i < nbttaglist.size(); ++i) {
|
||||||
|
removeUnwantedEntityTagsRecursively(nbttaglist.getCompound(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component getRichBlockName(BlockType blockType) {
|
public Component getRichBlockName(BlockType blockType) {
|
||||||
return TranslatableComponent.of(getBlockFromType(blockType).getDescriptionId());
|
return TranslatableComponent.of(getBlockFromType(blockType).getDescriptionId());
|
||||||
@ -487,21 +523,39 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
private static final LoadingCache<net.minecraft.world.level.block.state.properties.Property, Property<?>> PROPERTY_CACHE = CacheBuilder.newBuilder().build(new CacheLoader<net.minecraft.world.level.block.state.properties.Property, Property<?>>() {
|
private static final LoadingCache<net.minecraft.world.level.block.state.properties.Property, Property<?>> PROPERTY_CACHE = CacheBuilder
|
||||||
|
.newBuilder()
|
||||||
|
.build(new CacheLoader<net.minecraft.world.level.block.state.properties.Property, Property<?>>() {
|
||||||
@Override
|
@Override
|
||||||
public Property<?> load(net.minecraft.world.level.block.state.properties.Property state) throws Exception {
|
public Property<?> load(net.minecraft.world.level.block.state.properties.Property state) throws Exception {
|
||||||
if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) {
|
if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) {
|
||||||
return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues()));
|
return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues()));
|
||||||
} else if (state instanceof DirectionProperty) {
|
} else if (state instanceof DirectionProperty) {
|
||||||
return new DirectionalProperty(state.getName(),
|
return new DirectionalProperty(
|
||||||
(List<Direction>) state.getPossibleValues().stream().map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase(Locale.ROOT))).collect(Collectors.toList()));
|
state.getName(),
|
||||||
|
(List<Direction>) state
|
||||||
|
.getPossibleValues()
|
||||||
|
.stream()
|
||||||
|
.map(e -> Direction.valueOf(((StringRepresentable) e)
|
||||||
|
.getSerializedName()
|
||||||
|
.toUpperCase(Locale.ROOT)))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
);
|
||||||
} else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
|
} else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
|
||||||
return new EnumProperty(state.getName(),
|
return new EnumProperty(
|
||||||
(List<String>) state.getPossibleValues().stream().map(e -> ((StringRepresentable) e).getSerializedName()).collect(Collectors.toList()));
|
state.getName(),
|
||||||
|
(List<String>) state
|
||||||
|
.getPossibleValues()
|
||||||
|
.stream()
|
||||||
|
.map(e -> ((StringRepresentable) e).getSerializedName())
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
);
|
||||||
} else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) {
|
} else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) {
|
||||||
return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues()));
|
return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues()));
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("FastAsyncWorldEdit needs an update to support " + state.getClass().getSimpleName());
|
throw new IllegalArgumentException("WorldEdit needs an update to support " + state
|
||||||
|
.getClass()
|
||||||
|
.getSimpleName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -520,50 +574,68 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
//FAWE start - CompoundBinaryTag > CompoundTag
|
|
||||||
@Override
|
@Override
|
||||||
public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) {
|
public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) {
|
||||||
((CraftPlayer) player).getHandle().networkManager.send(ClientboundBlockEntityDataPacket.create(
|
var structureBlock = new StructureBlockEntity(
|
||||||
new StructureBlockEntity(
|
new BlockPos(pos.getX(), pos.getY(), pos.getZ()),
|
||||||
new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()),
|
|
||||||
Blocks.STRUCTURE_BLOCK.defaultBlockState()
|
Blocks.STRUCTURE_BLOCK.defaultBlockState()
|
||||||
),
|
);
|
||||||
__ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData)
|
structureBlock.setLevel(((CraftPlayer) player).getHandle().level());
|
||||||
|
((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create(
|
||||||
|
structureBlock,
|
||||||
|
(blockEntity, registryAccess) -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
//FAWE end
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendFakeOP(Player player) {
|
public void sendFakeOP(Player player) {
|
||||||
((CraftPlayer) player).getHandle().networkManager.send(new ClientboundEntityEventPacket(
|
((CraftPlayer) player).getHandle().connection.send(new ClientboundEntityEventPacket(
|
||||||
((CraftPlayer) player).getHandle(), (byte) 28
|
((CraftPlayer) player).getHandle(), (byte) 28
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public org.bukkit.inventory.ItemStack adapt(BaseItemStack item) {
|
public org.bukkit.inventory.ItemStack adapt(BaseItemStack item) {
|
||||||
ItemStack stack = new ItemStack(Registry.ITEM.get(ResourceLocation.tryParse(item.getType().getId())), item.getAmount());
|
final RegistryAccess.Frozen registryAccess = DedicatedServer.getServer().registryAccess();
|
||||||
stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData())));
|
ItemStack stack = new ItemStack(
|
||||||
|
registryAccess.registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(item.getType().getId())),
|
||||||
|
item.getAmount()
|
||||||
|
);
|
||||||
|
final CompoundTag nbt = (net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData());
|
||||||
|
final DataComponentPatch patch = COMPONENTS_CODEC
|
||||||
|
.parse(registryAccess.createSerializationContext(NbtOps.INSTANCE), nbt)
|
||||||
|
.getOrThrow();
|
||||||
|
stack.applyComponents(patch);
|
||||||
return CraftItemStack.asCraftMirror(stack);
|
return CraftItemStack.asCraftMirror(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) {
|
public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) {
|
||||||
|
final RegistryAccess.Frozen registryAccess = DedicatedServer.getServer().registryAccess();
|
||||||
final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
||||||
final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount());
|
final Tag tag = COMPONENTS_CODEC.encodeStart(
|
||||||
//FAWE start - CBT > CT
|
registryAccess.createSerializationContext(NbtOps.INSTANCE),
|
||||||
weStack.setNbt(((CompoundBinaryTag) toNativeBinary(nmsStack.getTag())));
|
nmsStack.getComponentsPatch()
|
||||||
//FAWE end
|
).getOrThrow();
|
||||||
return weStack;
|
return new BaseItemStack(
|
||||||
|
BukkitAdapter.asItemType(itemStack.getType()),
|
||||||
|
LazyReference.from(() -> (CompoundBinaryTag) toNativeBinary(tag)),
|
||||||
|
itemStack.getAmount()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final LoadingCache<ServerLevel, PaperweightFakePlayer> fakePlayers
|
||||||
|
= CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new));
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean simulateItemUse(org.bukkit.World world, BlockVector3 position, BaseItem item, Direction face) {
|
public boolean simulateItemUse(org.bukkit.World world, BlockVector3 position, BaseItem item, Direction face) {
|
||||||
CraftWorld craftWorld = (CraftWorld) world;
|
CraftWorld craftWorld = (CraftWorld) world;
|
||||||
ServerLevel worldServer = craftWorld.getHandle();
|
ServerLevel worldServer = craftWorld.getHandle();
|
||||||
ItemStack stack = CraftItemStack.asNMSCopy(BukkitAdapter.adapt(item instanceof BaseItemStack
|
ItemStack stack = CraftItemStack.asNMSCopy(adapt(
|
||||||
? ((BaseItemStack) item) : new BaseItemStack(item.getType(), item.getNbtData(), 1)));
|
item instanceof BaseItemStack
|
||||||
stack.setTag((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData()));
|
? ((BaseItemStack) item)
|
||||||
|
: new BaseItemStack(item.getType(), item.getNbtReference(), 1)
|
||||||
|
));
|
||||||
|
|
||||||
PaperweightFakePlayer fakePlayer;
|
PaperweightFakePlayer fakePlayer;
|
||||||
try {
|
try {
|
||||||
@ -572,20 +644,20 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack);
|
fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack);
|
||||||
fakePlayer.absMoveTo(position.getBlockX(), position.getBlockY(), position.getBlockZ(),
|
fakePlayer.absMoveTo(position.getX(), position.getY(), position.getZ(),
|
||||||
(float) face.toVector().toYaw(), (float) face.toVector().toPitch()
|
(float) face.toVector().toYaw(), (float) face.toVector().toPitch()
|
||||||
);
|
);
|
||||||
|
|
||||||
final BlockPos blockPos = new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ());
|
final BlockPos blockPos = new BlockPos(position.getX(), position.getY(), position.getZ());
|
||||||
final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos);
|
final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos);
|
||||||
final net.minecraft.core.Direction enumFacing = adapt(face);
|
final net.minecraft.core.Direction enumFacing = adapt(face);
|
||||||
BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false);
|
BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false);
|
||||||
UseOnContext context = new UseOnContext(fakePlayer, InteractionHand.MAIN_HAND, rayTrace);
|
UseOnContext context = new UseOnContext(fakePlayer, InteractionHand.MAIN_HAND, rayTrace);
|
||||||
InteractionResult result = stack.useOn(context, InteractionHand.MAIN_HAND);
|
InteractionResult result = stack.useOn(context);
|
||||||
if (result != InteractionResult.SUCCESS) {
|
if (result != InteractionResult.SUCCESS) {
|
||||||
if (worldServer
|
if (worldServer
|
||||||
.getBlockState(blockPos)
|
.getBlockState(blockPos)
|
||||||
.use(worldServer, fakePlayer, InteractionHand.MAIN_HAND, rayTrace)
|
.useItemOn(stack, worldServer, fakePlayer, InteractionHand.MAIN_HAND, rayTrace)
|
||||||
.consumesAction()) {
|
.consumesAction()) {
|
||||||
result = InteractionResult.SUCCESS;
|
result = InteractionResult.SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
@ -621,18 +693,18 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
Environment env = bukkitWorld.getEnvironment();
|
Environment env = bukkitWorld.getEnvironment();
|
||||||
ChunkGenerator gen = bukkitWorld.getGenerator();
|
ChunkGenerator gen = bukkitWorld.getGenerator();
|
||||||
|
|
||||||
Path tempDir = Files.createTempDirectory("FastAsyncWorldEditWorldGen");
|
Path tempDir = Files.createTempDirectory("WorldEditWorldGen");
|
||||||
LevelStorageSource levelStorage = LevelStorageSource.createDefault(tempDir);
|
LevelStorageSource levelStorage = LevelStorageSource.createDefault(tempDir);
|
||||||
ResourceKey<LevelStem> worldDimKey = getWorldDimKey(env);
|
ResourceKey<LevelStem> worldDimKey = getWorldDimKey(env);
|
||||||
try (LevelStorageSource.LevelStorageAccess session = levelStorage.createAccess("faweregentempworld", worldDimKey)) {
|
try (LevelStorageSource.LevelStorageAccess session = levelStorage.createAccess("faweregentempworld", worldDimKey)) {
|
||||||
ServerLevel originalWorld = ((CraftWorld) bukkitWorld).getHandle();
|
ServerLevel originalWorld = ((CraftWorld) bukkitWorld).getHandle();
|
||||||
PrimaryLevelData levelProperties = (PrimaryLevelData) originalWorld.getServer()
|
PrimaryLevelData levelProperties = (PrimaryLevelData) originalWorld.getServer()
|
||||||
.getWorldData().overworldData();
|
.getWorldData().overworldData();
|
||||||
WorldGenSettings originalOpts = levelProperties.worldGenSettings();
|
WorldOptions originalOpts = levelProperties.worldGenOptions();
|
||||||
|
|
||||||
long seed = options.getSeed().orElse(originalWorld.getSeed());
|
long seed = options.getSeed().orElse(originalWorld.getSeed());
|
||||||
WorldGenSettings newOpts = options.getSeed().isPresent()
|
WorldOptions newOpts = options.getSeed().isPresent()
|
||||||
? originalOpts.withSeed(levelProperties.isHardcore(), OptionalLong.of(seed))
|
? originalOpts.withSeed(OptionalLong.of(seed))
|
||||||
: originalOpts;
|
: originalOpts;
|
||||||
|
|
||||||
LevelSettings newWorldSettings = new LevelSettings(
|
LevelSettings newWorldSettings = new LevelSettings(
|
||||||
@ -642,23 +714,40 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
levelProperties.settings.difficulty(),
|
levelProperties.settings.difficulty(),
|
||||||
levelProperties.settings.allowCommands(),
|
levelProperties.settings.allowCommands(),
|
||||||
levelProperties.settings.gameRules(),
|
levelProperties.settings.gameRules(),
|
||||||
levelProperties.settings.getDataPackConfig()
|
levelProperties.settings.getDataConfiguration()
|
||||||
|
);
|
||||||
|
|
||||||
|
PrimaryLevelData.SpecialWorldProperty specialWorldProperty =
|
||||||
|
levelProperties.isFlatWorld()
|
||||||
|
? PrimaryLevelData.SpecialWorldProperty.FLAT
|
||||||
|
: levelProperties.isDebugWorld()
|
||||||
|
? PrimaryLevelData.SpecialWorldProperty.DEBUG
|
||||||
|
: PrimaryLevelData.SpecialWorldProperty.NONE;
|
||||||
|
|
||||||
|
PrimaryLevelData newWorldData = new PrimaryLevelData(
|
||||||
|
newWorldSettings,
|
||||||
|
newOpts,
|
||||||
|
specialWorldProperty,
|
||||||
|
Lifecycle.stable()
|
||||||
);
|
);
|
||||||
PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, Lifecycle.stable());
|
|
||||||
|
|
||||||
ServerLevel freshWorld = new ServerLevel(
|
ServerLevel freshWorld = new ServerLevel(
|
||||||
originalWorld.getServer(),
|
originalWorld.getServer(),
|
||||||
originalWorld.getServer().executor,
|
originalWorld.getServer().executor,
|
||||||
session, newWorldData,
|
session, newWorldData,
|
||||||
originalWorld.dimension(),
|
originalWorld.dimension(),
|
||||||
|
new LevelStem(
|
||||||
originalWorld.dimensionTypeRegistration(),
|
originalWorld.dimensionTypeRegistration(),
|
||||||
|
originalWorld.getChunkSource().getGenerator()
|
||||||
|
),
|
||||||
new NoOpWorldLoadListener(),
|
new NoOpWorldLoadListener(),
|
||||||
newOpts.dimensions().get(worldDimKey).generator(),
|
|
||||||
originalWorld.isDebug(),
|
originalWorld.isDebug(),
|
||||||
seed,
|
seed,
|
||||||
ImmutableList.of(),
|
ImmutableList.of(),
|
||||||
false,
|
false,
|
||||||
env, gen,
|
originalWorld.getRandomSequences(),
|
||||||
|
env,
|
||||||
|
gen,
|
||||||
bukkitWorld.getBiomeProvider()
|
bukkitWorld.getBiomeProvider()
|
||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
@ -678,7 +767,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
}
|
}
|
||||||
|
|
||||||
private BiomeType adapt(ServerLevel serverWorld, Biome origBiome) {
|
private BiomeType adapt(ServerLevel serverWorld, Biome origBiome) {
|
||||||
ResourceLocation key = serverWorld.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getKey(origBiome);
|
ResourceLocation key = serverWorld.registryAccess().registryOrThrow(Registries.BIOME).getKey(origBiome);
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -721,10 +810,8 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
Objects.requireNonNull(state);
|
Objects.requireNonNull(state);
|
||||||
BlockEntity blockEntity = chunk.getBlockEntity(pos);
|
BlockEntity blockEntity = chunk.getBlockEntity(pos);
|
||||||
if (blockEntity != null) {
|
if (blockEntity != null) {
|
||||||
net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId();
|
net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(serverWorld.registryAccess());
|
||||||
//FAWE start - BinaryTag
|
|
||||||
state = state.toBaseBlock(((CompoundBinaryTag) toNativeBinary(tag)));
|
state = state.toBaseBlock(((CompoundBinaryTag) toNativeBinary(tag)));
|
||||||
//FAWE end
|
|
||||||
}
|
}
|
||||||
extent.setBlock(vec, state.toBaseBlock());
|
extent.setBlock(vec, state.toBaseBlock());
|
||||||
if (options.shouldRegenBiomes()) {
|
if (options.shouldRegenBiomes()) {
|
||||||
@ -746,9 +833,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
try {
|
try {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
chunkLoadings.add(
|
chunkLoadings.add(
|
||||||
((CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>)
|
((CompletableFuture<ChunkResult<ChunkAccess>>)
|
||||||
getChunkFutureMethod.invoke(chunkManager, chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true))
|
getChunkFutureMethod.invoke(chunkManager, chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true))
|
||||||
.thenApply(either -> either.left().orElse(null))
|
.thenApply(either -> either.orElse(null))
|
||||||
);
|
);
|
||||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
throw new IllegalStateException("Couldn't load chunk for regen.", e);
|
throw new IllegalStateException("Couldn't load chunk for regen.", e);
|
||||||
@ -769,6 +856,15 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Set<SideEffect> SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet(
|
||||||
|
SideEffect.NEIGHBORS,
|
||||||
|
SideEffect.LIGHTING,
|
||||||
|
SideEffect.VALIDATION,
|
||||||
|
SideEffect.ENTITY_AI,
|
||||||
|
SideEffect.EVENTS,
|
||||||
|
SideEffect.UPDATE
|
||||||
|
);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<SideEffect> getSupportedSideEffects() {
|
public Set<SideEffect> getSupportedSideEffects() {
|
||||||
return SUPPORTED_SIDE_EFFECTS;
|
return SUPPORTED_SIDE_EFFECTS;
|
||||||
@ -797,7 +893,6 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
* @param foreign non-native NMS NBT structure
|
* @param foreign non-native NMS NBT structure
|
||||||
* @return native WorldEdit NBT structure
|
* @return native WorldEdit NBT structure
|
||||||
*/
|
*/
|
||||||
//FAWE start - BinaryTag
|
|
||||||
@Override
|
@Override
|
||||||
public BinaryTag toNativeBinary(net.minecraft.nbt.Tag foreign) {
|
public BinaryTag toNativeBinary(net.minecraft.nbt.Tag foreign) {
|
||||||
if (foreign == null) {
|
if (foreign == null) {
|
||||||
@ -830,7 +925,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
try {
|
try {
|
||||||
return toNativeList((net.minecraft.nbt.ListTag) foreign);
|
return toNativeList((net.minecraft.nbt.ListTag) foreign);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
LOGGER.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e);
|
logger.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e);
|
||||||
return ListBinaryTag.empty();
|
return ListBinaryTag.empty();
|
||||||
}
|
}
|
||||||
} else if (foreign instanceof net.minecraft.nbt.LongTag) {
|
} else if (foreign instanceof net.minecraft.nbt.LongTag) {
|
||||||
@ -855,7 +950,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
* @throws IllegalArgumentException on error
|
* @throws IllegalArgumentException on error
|
||||||
*/
|
*/
|
||||||
private ListBinaryTag toNativeList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException {
|
private ListBinaryTag toNativeList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException {
|
||||||
ListBinaryTag.Builder<BinaryTag> values = ListBinaryTag.builder();
|
ListBinaryTag.Builder values = ListBinaryTag.builder();
|
||||||
|
|
||||||
for (net.minecraft.nbt.Tag tag : foreign) {
|
for (net.minecraft.nbt.Tag tag : foreign) {
|
||||||
values.add(toNativeBinary(tag));
|
values.add(toNativeBinary(tag));
|
||||||
@ -895,8 +990,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
return new net.minecraft.nbt.IntArrayTag(((IntArrayBinaryTag) foreign).value());
|
return new net.minecraft.nbt.IntArrayTag(((IntArrayBinaryTag) foreign).value());
|
||||||
} else if (foreign instanceof LongArrayBinaryTag) {
|
} else if (foreign instanceof LongArrayBinaryTag) {
|
||||||
return new net.minecraft.nbt.LongArrayTag(((LongArrayBinaryTag) foreign).value());
|
return new net.minecraft.nbt.LongArrayTag(((LongArrayBinaryTag) foreign).value());
|
||||||
} else if (foreign instanceof ListBinaryTag foreignList) {
|
} else if (foreign instanceof ListBinaryTag) {
|
||||||
net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag();
|
net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag();
|
||||||
|
ListBinaryTag foreignList = (ListBinaryTag) foreign;
|
||||||
for (BinaryTag t : foreignList) {
|
for (BinaryTag t : foreignList) {
|
||||||
tag.add(fromNativeBinary(t));
|
tag.add(fromNativeBinary(t));
|
||||||
}
|
}
|
||||||
@ -913,7 +1009,6 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName());
|
throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//FAWE end
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsWatchdog() {
|
public boolean supportsWatchdog() {
|
||||||
@ -925,54 +1020,6 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
watchdog.tick();
|
watchdog.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MojangWatchdog implements Watchdog {
|
|
||||||
|
|
||||||
private final DedicatedServer server;
|
|
||||||
private final Field tickField;
|
|
||||||
|
|
||||||
MojangWatchdog(DedicatedServer server) throws NoSuchFieldException {
|
|
||||||
this.server = server;
|
|
||||||
Field tickField = MinecraftServer.class.getDeclaredField(
|
|
||||||
Refraction.pickName("nextTickTime", "ao")
|
|
||||||
);
|
|
||||||
tickField.setAccessible(true);
|
|
||||||
this.tickField = tickField;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
|
||||||
try {
|
|
||||||
tickField.set(server, Util.getMillis());
|
|
||||||
} catch (IllegalAccessException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class NoOpWorldLoadListener implements ChunkProgressListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateSpawnPos(ChunkPos spawnPos) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStatusChange(ChunkPos pos, @Nullable ChunkStatus status) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stop() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setChunkRadius(int radius) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SpigotWatchdog implements Watchdog {
|
private class SpigotWatchdog implements Watchdog {
|
||||||
|
|
||||||
private final Field instanceField;
|
private final Field instanceField;
|
||||||
@ -996,10 +1043,61 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
WatchdogThread.tick();
|
WatchdogThread.tick();
|
||||||
}
|
}
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
LOGGER.log(Level.WARNING, "Failed to tick watchdog", e);
|
logger.log(Level.WARNING, "Failed to tick watchdog", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class MojangWatchdog implements Watchdog {
|
||||||
|
|
||||||
|
private final DedicatedServer server;
|
||||||
|
private final Field tickField;
|
||||||
|
|
||||||
|
MojangWatchdog(DedicatedServer server) throws NoSuchFieldException {
|
||||||
|
this.server = server;
|
||||||
|
Field tickField = MinecraftServer.class.getDeclaredField(
|
||||||
|
Refraction.pickName("nextTickTime", "ah")
|
||||||
|
);
|
||||||
|
if (tickField.getType() != long.class) {
|
||||||
|
throw new IllegalStateException("nextTickTime is not a long field, mapping is likely incorrect");
|
||||||
|
}
|
||||||
|
tickField.setAccessible(true);
|
||||||
|
this.tickField = tickField;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
try {
|
||||||
|
tickField.set(server, Util.getMillis());
|
||||||
|
} catch (IllegalAccessException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class NoOpWorldLoadListener implements ChunkProgressListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSpawnPos(ChunkPos spawnPos) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStatusChange(
|
||||||
|
final ChunkPos pos,
|
||||||
|
@org.jetbrains.annotations.Nullable final net.minecraft.world.level.chunk.status.ChunkStatus status
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
@ -17,18 +17,19 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R2;
|
package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4;
|
||||||
|
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import net.minecraft.network.chat.ChatType;
|
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.network.protocol.game.ServerboundClientInformationPacket;
|
import net.minecraft.server.level.ClientInformation;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.stats.Stat;
|
import net.minecraft.stats.Stat;
|
||||||
import net.minecraft.world.MenuProvider;
|
import net.minecraft.world.MenuProvider;
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
import net.minecraft.world.damagesource.DamageSource;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.HumanoidArm;
|
||||||
|
import net.minecraft.world.entity.player.ChatVisiblity;
|
||||||
import net.minecraft.world.level.block.entity.SignBlockEntity;
|
import net.minecraft.world.level.block.entity.SignBlockEntity;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||||
@ -37,15 +38,14 @@ import java.util.OptionalInt;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
class PaperweightFakePlayer extends ServerPlayer {
|
class PaperweightFakePlayer extends ServerPlayer {
|
||||||
|
private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(UUID.nameUUIDFromBytes("worldedit".getBytes()), "[WorldEdit]");
|
||||||
private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(
|
|
||||||
UUID.nameUUIDFromBytes("worldedit".getBytes()),
|
|
||||||
"[WorldEdit]"
|
|
||||||
);
|
|
||||||
private static final Vec3 ORIGIN = new Vec3(0.0D, 0.0D, 0.0D);
|
private static final Vec3 ORIGIN = new Vec3(0.0D, 0.0D, 0.0D);
|
||||||
|
private static final ClientInformation FAKE_CLIENT_INFO = new ClientInformation(
|
||||||
|
"en_US", 16, ChatVisiblity.FULL, true, 0, HumanoidArm.LEFT, false, false
|
||||||
|
);
|
||||||
|
|
||||||
PaperweightFakePlayer(ServerLevel world) {
|
PaperweightFakePlayer(ServerLevel world) {
|
||||||
super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE);
|
super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE, FAKE_CLIENT_INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -72,17 +72,13 @@ class PaperweightFakePlayer extends ServerPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateOptions(ServerboundClientInformationPacket packet) {
|
public void updateOptions(ClientInformation clientOptions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void displayClientMessage(Component message, boolean actionBar) {
|
public void displayClientMessage(Component message, boolean actionBar) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendMessage(Component message, ChatType type, UUID sender) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void awardStat(Stat<?> stat, int amount) {
|
public void awardStat(Stat<?> stat, int amount) {
|
||||||
}
|
}
|
||||||
@ -97,7 +93,6 @@ class PaperweightFakePlayer extends ServerPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void openTextEdit(SignBlockEntity sign) {
|
public void openTextEdit(SignBlockEntity sign, boolean front) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -17,7 +17,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R2;
|
package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4;
|
||||||
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
||||||
@ -27,21 +27,19 @@ import com.sk89q.worldedit.util.SideEffectSet;
|
|||||||
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.server.level.ChunkHolder;
|
import net.minecraft.server.level.FullChunkStatus;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
import org.bukkit.craftbukkit.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData;
|
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class PaperweightWorldNativeAccess implements
|
public class PaperweightWorldNativeAccess implements WorldNativeAccess<LevelChunk, net.minecraft.world.level.block.state.BlockState, BlockPos> {
|
||||||
WorldNativeAccess<LevelChunk, net.minecraft.world.level.block.state.BlockState, BlockPos> {
|
|
||||||
|
|
||||||
private static final int UPDATE = 1;
|
private static final int UPDATE = 1;
|
||||||
private static final int NOTIFY = 2;
|
private static final int NOTIFY = 2;
|
||||||
|
|
||||||
@ -83,19 +81,12 @@ public class PaperweightWorldNativeAccess implements
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public net.minecraft.world.level.block.state.BlockState setBlockState(
|
public net.minecraft.world.level.block.state.BlockState setBlockState(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState state) {
|
||||||
LevelChunk chunk,
|
|
||||||
BlockPos position,
|
|
||||||
net.minecraft.world.level.block.state.BlockState state
|
|
||||||
) {
|
|
||||||
return chunk.setBlockState(position, state, false, this.sideEffectSet.shouldApply(SideEffect.UPDATE));
|
return chunk.setBlockState(position, state, false, this.sideEffectSet.shouldApply(SideEffect.UPDATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition(
|
public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition(net.minecraft.world.level.block.state.BlockState block, BlockPos position) {
|
||||||
net.minecraft.world.level.block.state.BlockState block,
|
|
||||||
BlockPos position
|
|
||||||
) {
|
|
||||||
return Block.updateFromNeighbourShapes(block, getWorld(), position);
|
return Block.updateFromNeighbourShapes(block, getWorld(), position);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,12 +106,7 @@ public class PaperweightWorldNativeAccess implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyBlockUpdate(
|
public void notifyBlockUpdate(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) {
|
||||||
LevelChunk chunk,
|
|
||||||
BlockPos position,
|
|
||||||
net.minecraft.world.level.block.state.BlockState oldState,
|
|
||||||
net.minecraft.world.level.block.state.BlockState newState
|
|
||||||
) {
|
|
||||||
if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) {
|
if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) {
|
||||||
getWorld().sendBlockUpdated(position, oldState, newState, UPDATE | NOTIFY);
|
getWorld().sendBlockUpdated(position, oldState, newState, UPDATE | NOTIFY);
|
||||||
}
|
}
|
||||||
@ -128,7 +114,7 @@ public class PaperweightWorldNativeAccess implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isChunkTicking(LevelChunk chunk) {
|
public boolean isChunkTicking(LevelChunk chunk) {
|
||||||
return chunk.getFullStatus().isOrAfter(ChunkHolder.FullChunkStatus.TICKING);
|
return chunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -139,11 +125,7 @@ public class PaperweightWorldNativeAccess implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyNeighbors(
|
public void notifyNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) {
|
||||||
BlockPos pos,
|
|
||||||
net.minecraft.world.level.block.state.BlockState oldState,
|
|
||||||
net.minecraft.world.level.block.state.BlockState newState
|
|
||||||
) {
|
|
||||||
ServerLevel world = getWorld();
|
ServerLevel world = getWorld();
|
||||||
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
|
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
|
||||||
world.updateNeighborsAt(pos, oldState.getBlock());
|
world.updateNeighborsAt(pos, oldState.getBlock());
|
||||||
@ -162,27 +144,20 @@ public class PaperweightWorldNativeAccess implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not sure why neighborChanged is deprecated
|
||||||
private void fireNeighborChanged(BlockPos pos, ServerLevel world, Block block, BlockPos neighborPos) {
|
private void fireNeighborChanged(BlockPos pos, ServerLevel world, Block block, BlockPos neighborPos) {
|
||||||
world.getBlockState(neighborPos).neighborChanged(world, neighborPos, block, pos, false);
|
world.getBlockState(neighborPos).handleNeighborChanged(world, neighborPos, block, pos, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateNeighbors(
|
public void updateNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState, int recursionLimit) {
|
||||||
BlockPos pos,
|
|
||||||
net.minecraft.world.level.block.state.BlockState oldState,
|
|
||||||
net.minecraft.world.level.block.state.BlockState newState,
|
|
||||||
int recursionLimit
|
|
||||||
) {
|
|
||||||
ServerLevel world = getWorld();
|
ServerLevel world = getWorld();
|
||||||
// a == updateNeighbors
|
// a == updateNeighbors
|
||||||
// b == updateDiagonalNeighbors
|
// b == updateDiagonalNeighbors
|
||||||
oldState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit);
|
oldState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit);
|
||||||
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
|
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
|
||||||
CraftWorld craftWorld = world.getWorld();
|
CraftWorld craftWorld = world.getWorld();
|
||||||
BlockPhysicsEvent event = new BlockPhysicsEvent(
|
BlockPhysicsEvent event = new BlockPhysicsEvent(craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()), CraftBlockData.fromData(newState));
|
||||||
craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()),
|
|
||||||
CraftBlockData.fromData(newState)
|
|
||||||
);
|
|
||||||
world.getCraftServer().getPluginManager().callEvent(event);
|
world.getCraftServer().getPluginManager().callEvent(event);
|
||||||
if (event.isCancelled()) {
|
if (event.isCancelled()) {
|
||||||
return;
|
return;
|
||||||
@ -193,19 +168,13 @@ public class PaperweightWorldNativeAccess implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBlockStateChange(
|
public void onBlockStateChange(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) {
|
||||||
BlockPos pos,
|
|
||||||
net.minecraft.world.level.block.state.BlockState oldState,
|
|
||||||
net.minecraft.world.level.block.state.BlockState newState
|
|
||||||
) {
|
|
||||||
getWorld().onBlockStateChange(pos, oldState, newState);
|
getWorld().onBlockStateChange(pos, oldState, newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
//FAWE start
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public void flush() {
|
||||||
|
|
||||||
}
|
}
|
||||||
//FAWE end
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,28 +1,24 @@
|
|||||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||||
|
|
||||||
import com.google.common.base.Suppliers;
|
import com.google.common.base.Suppliers;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.util.ReflectionUtil;
|
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt.PaperweightLazyCompoundTag;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
|
||||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt.PaperweightLazyCompoundTag;
|
|
||||||
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.server.dedicated.DedicatedServer;
|
||||||
import net.minecraft.world.level.EmptyBlockGetter;
|
import net.minecraft.world.level.EmptyBlockGetter;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.EntityBlock;
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.material.Material;
|
import net.minecraft.world.level.material.Fluids;
|
||||||
import net.minecraft.world.level.material.PushReaction;
|
import net.minecraft.world.level.material.PushReaction;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData;
|
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||||
|
|
||||||
public class PaperweightBlockMaterial implements BlockMaterial {
|
public class PaperweightBlockMaterial implements BlockMaterial {
|
||||||
|
|
||||||
private final Block block;
|
private final Block block;
|
||||||
private final BlockState blockState;
|
private final BlockState blockState;
|
||||||
private final Material material;
|
|
||||||
private final boolean isTranslucent;
|
|
||||||
private final CraftBlockData craftBlockData;
|
private final CraftBlockData craftBlockData;
|
||||||
private final org.bukkit.Material craftMaterial;
|
private final org.bukkit.Material craftMaterial;
|
||||||
private final int opacity;
|
private final int opacity;
|
||||||
@ -35,22 +31,16 @@ public class PaperweightBlockMaterial implements BlockMaterial {
|
|||||||
public PaperweightBlockMaterial(Block block, BlockState blockState) {
|
public PaperweightBlockMaterial(Block block, BlockState blockState) {
|
||||||
this.block = block;
|
this.block = block;
|
||||||
this.blockState = blockState;
|
this.blockState = blockState;
|
||||||
this.material = blockState.getMaterial();
|
|
||||||
this.craftBlockData = CraftBlockData.fromData(blockState);
|
this.craftBlockData = CraftBlockData.fromData(blockState);
|
||||||
this.craftMaterial = craftBlockData.getMaterial();
|
this.craftMaterial = craftBlockData.getMaterial();
|
||||||
BlockBehaviour.Properties blockInfo = ReflectionUtil.getField(BlockBehaviour.class, block, Refraction.pickName(
|
|
||||||
"properties", "aO"));
|
|
||||||
this.isTranslucent = !(boolean) ReflectionUtil.getField(BlockBehaviour.Properties.class, blockInfo,
|
|
||||||
Refraction.pickName("canOcclude", "n")
|
|
||||||
);
|
|
||||||
opacity = blockState.getLightBlock(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
|
opacity = blockState.getLightBlock(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
|
||||||
BlockEntity tileEntity = !(block instanceof EntityBlock) ? null : ((EntityBlock) block).newBlockEntity(
|
BlockEntity tileEntity = !(block instanceof EntityBlock) ? null : ((EntityBlock) block).newBlockEntity(
|
||||||
BlockPos.ZERO,
|
BlockPos.ZERO,
|
||||||
blockState
|
blockState
|
||||||
);
|
);
|
||||||
tile = tileEntity == null
|
tile = tileEntity == null ? null : new PaperweightLazyCompoundTag(
|
||||||
? null
|
Suppliers.memoize(() -> tileEntity.saveWithId(DedicatedServer.getServer().registryAccess()))
|
||||||
: new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Block getBlock() {
|
public Block getBlock() {
|
||||||
@ -65,10 +55,6 @@ public class PaperweightBlockMaterial implements BlockMaterial {
|
|||||||
return craftBlockData;
|
return craftBlockData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Material getMaterial() {
|
|
||||||
return material;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAir() {
|
public boolean isAir() {
|
||||||
return blockState.isAir();
|
return blockState.isAir();
|
||||||
@ -81,7 +67,7 @@ public class PaperweightBlockMaterial implements BlockMaterial {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOpaque() {
|
public boolean isOpaque() {
|
||||||
return material.isSolidBlocking();
|
return blockState.canOcclude();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -91,12 +77,13 @@ public class PaperweightBlockMaterial implements BlockMaterial {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLiquid() {
|
public boolean isLiquid() {
|
||||||
return material.isLiquid();
|
return !blockState.getFluidState().is(Fluids.EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSolid() {
|
public boolean isSolid() {
|
||||||
return material.isSolid();
|
// No access to world -> EmptyBlockGetter
|
||||||
|
return blockState.isSolidRender(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -126,27 +113,27 @@ public class PaperweightBlockMaterial implements BlockMaterial {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFragileWhenPushed() {
|
public boolean isFragileWhenPushed() {
|
||||||
return material.getPushReaction() == PushReaction.DESTROY;
|
return blockState.getPistonPushReaction() == PushReaction.DESTROY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isUnpushable() {
|
public boolean isUnpushable() {
|
||||||
return material.getPushReaction() == PushReaction.BLOCK;
|
return blockState.getPistonPushReaction() == PushReaction.BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isTicksRandomly() {
|
public boolean isTicksRandomly() {
|
||||||
return block.isRandomlyTicking(blockState);
|
return blockState.isRandomlyTicking();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isMovementBlocker() {
|
public boolean isMovementBlocker() {
|
||||||
return material.isSolid();
|
return craftMaterial.isSolid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isBurnable() {
|
public boolean isBurnable() {
|
||||||
return material.isFlammable();
|
return craftMaterial.isBurnable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -157,12 +144,12 @@ public class PaperweightBlockMaterial implements BlockMaterial {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isReplacedDuringPlacement() {
|
public boolean isReplacedDuringPlacement() {
|
||||||
return material.isReplaceable();
|
return blockState.canBeReplaced();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isTranslucent() {
|
public boolean isTranslucent() {
|
||||||
return isTranslucent;
|
return !blockState.canOcclude();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -183,7 +170,7 @@ public class PaperweightBlockMaterial implements BlockMaterial {
|
|||||||
@Override
|
@Override
|
||||||
public int getMapColor() {
|
public int getMapColor() {
|
||||||
// rgb field
|
// rgb field
|
||||||
return material.getColor().col;
|
return block.defaultMapColor().col;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||||
|
|
||||||
import com.fastasyncworldedit.bukkit.adapter.FaweAdapter;
|
import com.fastasyncworldedit.bukkit.adapter.FaweAdapter;
|
||||||
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
||||||
@ -12,14 +12,13 @@ import com.fastasyncworldedit.core.util.NbtUtils;
|
|||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
import com.sk89q.jnbt.Tag;
|
import com.sk89q.jnbt.Tag;
|
||||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||||
import com.sk89q.worldedit.blocks.TileEntityBlock;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R2.PaperweightAdapter;
|
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt.PaperweightLazyCompoundTag;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt.PaperweightLazyCompoundTag;
|
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.regen.PaperweightRegen;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.regen.PaperweightRegen;
|
|
||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
||||||
@ -35,6 +34,7 @@ import com.sk89q.worldedit.registry.state.Property;
|
|||||||
import com.sk89q.worldedit.util.Direction;
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.util.SideEffect;
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
import com.sk89q.worldedit.util.SideEffectSet;
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
|
import com.sk89q.worldedit.util.concurrency.LazyReference;
|
||||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||||
import com.sk89q.worldedit.util.nbt.BinaryTag;
|
import com.sk89q.worldedit.util.nbt.BinaryTag;
|
||||||
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
||||||
@ -45,7 +45,6 @@ import com.sk89q.worldedit.world.block.BaseBlock;
|
|||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
import com.sk89q.worldedit.world.block.BlockType;
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import com.sk89q.worldedit.world.entity.EntityType;
|
import com.sk89q.worldedit.world.entity.EntityType;
|
||||||
import com.sk89q.worldedit.world.item.ItemType;
|
import com.sk89q.worldedit.world.item.ItemType;
|
||||||
@ -53,44 +52,48 @@ import com.sk89q.worldedit.world.registry.BlockMaterial;
|
|||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
import net.minecraft.core.WritableRegistry;
|
import net.minecraft.core.WritableRegistry;
|
||||||
import net.minecraft.nbt.IntTag;
|
import net.minecraft.core.component.DataComponentPatch;
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.nbt.NbtOps;
|
||||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
|
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.dedicated.DedicatedServer;
|
||||||
import net.minecraft.server.level.ChunkHolder;
|
import net.minecraft.server.level.ChunkHolder;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.util.StringRepresentable;
|
import net.minecraft.util.StringRepresentable;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftChunk;
|
import org.bukkit.craftbukkit.CraftServer;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftServer;
|
import org.bukkit.craftbukkit.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData;
|
import org.bukkit.craftbukkit.entity.CraftEntity;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity;
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack;
|
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.util.CraftNamespacedKey;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -104,11 +107,24 @@ import java.util.function.Supplier;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static net.minecraft.core.registries.Registries.BIOME;
|
||||||
|
|
||||||
public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.Tag, ServerLevel> {
|
public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.Tag, ServerLevel> {
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||||
|
private static Method CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE;
|
||||||
|
private static final Codec<DataComponentPatch> COMPONENTS_CODEC = DataComponentPatch.CODEC.optionalFieldOf(
|
||||||
|
"components", DataComponentPatch.EMPTY
|
||||||
|
).codec();
|
||||||
|
|
||||||
private final PaperweightAdapter parent;
|
static {
|
||||||
|
try {
|
||||||
|
CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE = ChunkHolder.class.getDeclaredMethod("wasAccessibleSinceLastSave");
|
||||||
|
} catch (NoSuchMethodException ignored) { // may not be present in newer paper versions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4.PaperweightAdapter parent;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Code that may break between versions of Minecraft
|
// Code that may break between versions of Minecraft
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -119,7 +135,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
private Map<String, List<Property<?>>> allBlockProperties = null;
|
private Map<String, List<Property<?>>> allBlockProperties = null;
|
||||||
|
|
||||||
public PaperweightFaweAdapter() throws NoSuchFieldException, NoSuchMethodException {
|
public PaperweightFaweAdapter() throws NoSuchFieldException, NoSuchMethodException {
|
||||||
this.parent = new PaperweightAdapter();
|
this.parent = new com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4.PaperweightAdapter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -128,6 +144,10 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
return resourceLocation == null ? null : resourceLocation.toString();
|
return resourceLocation == null ? null : resourceLocation.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) {
|
||||||
|
entity.save(compoundTag);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BukkitImplAdapter<net.minecraft.nbt.Tag> getParent() {
|
public BukkitImplAdapter<net.minecraft.nbt.Tag> getParent() {
|
||||||
return parent;
|
return parent;
|
||||||
@ -219,7 +239,8 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Block getBlock(BlockType blockType) {
|
public Block getBlock(BlockType blockType) {
|
||||||
return Registry.BLOCK.get(new ResourceLocation(blockType.getNamespace(), blockType.getResource()));
|
return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.BLOCK)
|
||||||
|
.get(new ResourceLocation(blockType.getNamespace(), blockType.getResource()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@ -264,7 +285,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
// Read the NBT data
|
// Read the NBT data
|
||||||
BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK);
|
BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK);
|
||||||
if (blockEntity != null) {
|
if (blockEntity != null) {
|
||||||
net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId();
|
net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(DedicatedServer.getServer().registryAccess());
|
||||||
return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag));
|
return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -277,54 +298,6 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
return SideEffectSet.defaults().getSideEffectsToApply();
|
return SideEffectSet.defaults().getSideEffectsToApply();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setBlock(org.bukkit.Chunk chunk, int x, int y, int z, BlockStateHolder state, boolean update) {
|
|
||||||
CraftChunk craftChunk = (CraftChunk) chunk;
|
|
||||||
LevelChunk levelChunk = craftChunk.getHandle();
|
|
||||||
Level level = levelChunk.getLevel();
|
|
||||||
|
|
||||||
BlockPos blockPos = new BlockPos(x, y, z);
|
|
||||||
net.minecraft.world.level.block.state.BlockState blockState = ((PaperweightBlockMaterial) state.getMaterial()).getState();
|
|
||||||
LevelChunkSection[] levelChunkSections = levelChunk.getSections();
|
|
||||||
int y4 = y >> 4;
|
|
||||||
LevelChunkSection section = levelChunkSections[y4];
|
|
||||||
|
|
||||||
net.minecraft.world.level.block.state.BlockState existing;
|
|
||||||
if (section == null) {
|
|
||||||
existing = ((PaperweightBlockMaterial) BlockTypes.AIR.getDefaultState().getMaterial()).getState();
|
|
||||||
} else {
|
|
||||||
existing = section.getBlockState(x & 15, y & 15, z & 15);
|
|
||||||
}
|
|
||||||
|
|
||||||
levelChunk.removeBlockEntity(blockPos); // Force delete the old tile entity
|
|
||||||
|
|
||||||
CompoundBinaryTag compoundTag = state instanceof BaseBlock ? state.getNbt() : null;
|
|
||||||
if (compoundTag != null || existing instanceof TileEntityBlock) {
|
|
||||||
level.setBlock(blockPos, blockState, 0);
|
|
||||||
// remove tile
|
|
||||||
if (compoundTag != null) {
|
|
||||||
// We will assume that the tile entity was created for us,
|
|
||||||
// though we do not do this on the Forge version
|
|
||||||
BlockEntity blockEntity = level.getBlockEntity(blockPos);
|
|
||||||
if (blockEntity != null) {
|
|
||||||
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) fromNativeBinary(compoundTag);
|
|
||||||
tag.put("x", IntTag.valueOf(x));
|
|
||||||
tag.put("y", IntTag.valueOf(y));
|
|
||||||
tag.put("z", IntTag.valueOf(z));
|
|
||||||
blockEntity.load(tag); // readTagIntoTileEntity - load data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (existing == blockState) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
levelChunk.setBlockState(blockPos, blockState, false);
|
|
||||||
}
|
|
||||||
if (update) {
|
|
||||||
level.getMinecraftWorld().sendBlockUpdated(blockPos, existing, blockState, 0);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) {
|
public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) {
|
||||||
return new PaperweightFaweWorldNativeAccess(this, new WeakReference<>(getServerLevel(world)));
|
return new PaperweightFaweWorldNativeAccess(this, new WeakReference<>(getServerLevel(world)));
|
||||||
@ -343,7 +316,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
|
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
|
||||||
Supplier<CompoundBinaryTag> saveTag = () -> {
|
Supplier<CompoundBinaryTag> saveTag = () -> {
|
||||||
final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag();
|
final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag();
|
||||||
PaperweightPlatformAdapter.readEntityIntoTag(mcEntity, minecraftTag);
|
readEntityIntoTag(mcEntity, minecraftTag);
|
||||||
//add Id for AbstractChangeSet to work
|
//add Id for AbstractChangeSet to work
|
||||||
final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag);
|
final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag);
|
||||||
final Map<String, BinaryTag> tags = NbtUtils.getCompoundBinaryTagValues(tag);
|
final Map<String, BinaryTag> tags = NbtUtils.getCompoundBinaryTagValues(tag);
|
||||||
@ -474,7 +447,8 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket chunkPacket) {
|
public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket chunkPacket) {
|
||||||
ServerLevel nmsWorld = getServerLevel(world);
|
ServerLevel nmsWorld = getServerLevel(world);
|
||||||
ChunkHolder map = PaperweightPlatformAdapter.getPlayerChunk(nmsWorld, chunkPacket.getChunkX(), chunkPacket.getChunkZ());
|
ChunkHolder map = PaperweightPlatformAdapter.getPlayerChunk(nmsWorld, chunkPacket.getChunkX(), chunkPacket.getChunkZ());
|
||||||
if (map != null && map.wasAccessibleSinceLastSave()) {
|
if (map != null && wasAccessibleSinceLastSave(map)) {
|
||||||
|
boolean flag = false;
|
||||||
// PlayerChunk.d players = map.players;
|
// PlayerChunk.d players = map.players;
|
||||||
Stream<ServerPlayer> stream = /*players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag)
|
Stream<ServerPlayer> stream = /*players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag)
|
||||||
*/ Stream.empty();
|
*/ Stream.empty();
|
||||||
@ -516,11 +490,18 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public org.bukkit.inventory.ItemStack adapt(BaseItemStack baseItemStack) {
|
public org.bukkit.inventory.ItemStack adapt(BaseItemStack baseItemStack) {
|
||||||
|
final RegistryAccess.Frozen registryAccess = DedicatedServer.getServer().registryAccess();
|
||||||
ItemStack stack = new ItemStack(
|
ItemStack stack = new ItemStack(
|
||||||
Registry.ITEM.get(ResourceLocation.tryParse(baseItemStack.getType().getId())),
|
registryAccess.registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(baseItemStack.getType().getId())),
|
||||||
baseItemStack.getAmount()
|
baseItemStack.getAmount()
|
||||||
);
|
);
|
||||||
stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(baseItemStack.getNbtData())));
|
final CompoundTag nbt = (net.minecraft.nbt.CompoundTag) fromNative(baseItemStack.getNbtData());
|
||||||
|
if (nbt != null) {
|
||||||
|
final DataComponentPatch patch = COMPONENTS_CODEC
|
||||||
|
.parse(registryAccess.createSerializationContext(NbtOps.INSTANCE), nbt)
|
||||||
|
.getOrThrow();
|
||||||
|
stack.applyComponents(patch);
|
||||||
|
}
|
||||||
return CraftItemStack.asCraftMirror(stack);
|
return CraftItemStack.asCraftMirror(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -547,29 +528,19 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
return ((CraftWorld) world).getHandle();
|
return ((CraftWorld) world).getHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<org.bukkit.entity.Entity> getEntities(org.bukkit.World world) {
|
|
||||||
// Quickly add each entity to a list copy.
|
|
||||||
List<Entity> mcEntities = new ArrayList<>();
|
|
||||||
getServerLevel(world).entityManager.getEntityGetter().getAll().forEach(mcEntities::add);
|
|
||||||
|
|
||||||
List<org.bukkit.entity.Entity> list = new ArrayList<>();
|
|
||||||
mcEntities.forEach((mcEnt) -> {
|
|
||||||
org.bukkit.entity.Entity bukkitEntity = mcEnt.getBukkitEntity();
|
|
||||||
if (bukkitEntity.isValid()) {
|
|
||||||
list.add(bukkitEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) {
|
public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) {
|
||||||
|
final RegistryAccess.Frozen registryAccess = DedicatedServer.getServer().registryAccess();
|
||||||
final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
||||||
final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount());
|
final net.minecraft.nbt.Tag tag = COMPONENTS_CODEC.encodeStart(
|
||||||
weStack.setNbt(((CompoundBinaryTag) toNativeBinary(nmsStack.getTag())));
|
registryAccess.createSerializationContext(NbtOps.INSTANCE),
|
||||||
return weStack;
|
nmsStack.getComponentsPatch()
|
||||||
|
).getOrThrow();
|
||||||
|
return new BaseItemStack(
|
||||||
|
BukkitAdapter.asItemType(itemStack.getType()),
|
||||||
|
LazyReference.from(() -> (CompoundBinaryTag) toNativeBinary(tag)),
|
||||||
|
itemStack.getAmount()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -577,17 +548,12 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
return parent.toNative(foreign);
|
return parent.toNative(foreign);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BinaryTag toNativeBinary(final net.minecraft.nbt.Tag foreign) {
|
|
||||||
return parent.toNativeBinary(foreign);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public net.minecraft.nbt.Tag fromNative(Tag foreign) {
|
public net.minecraft.nbt.Tag fromNative(Tag foreign) {
|
||||||
if (foreign instanceof PaperweightLazyCompoundTag) {
|
if (foreign instanceof PaperweightLazyCompoundTag) {
|
||||||
return ((PaperweightLazyCompoundTag) foreign).get();
|
return ((PaperweightLazyCompoundTag) foreign).get();
|
||||||
}
|
}
|
||||||
return (net.minecraft.nbt.Tag) parent.fromNative(foreign);
|
return parent.fromNative(foreign);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -605,7 +571,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
final Registry<Biome> registry = MinecraftServer
|
final Registry<Biome> registry = MinecraftServer
|
||||||
.getServer()
|
.getServer()
|
||||||
.registryAccess()
|
.registryAccess()
|
||||||
.ownedRegistryOrThrow(Registry.BIOME_REGISTRY);
|
.registryOrThrow(BIOME);
|
||||||
ResourceLocation resourceLocation = ResourceLocation.tryParse(biomeType.getId());
|
ResourceLocation resourceLocation = ResourceLocation.tryParse(biomeType.getId());
|
||||||
Biome biome = registry.get(resourceLocation);
|
Biome biome = registry.get(resourceLocation);
|
||||||
return registry.getId(biome);
|
return registry.getId(biome);
|
||||||
@ -616,8 +582,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
WritableRegistry<Biome> biomeRegistry = (WritableRegistry<Biome>) ((CraftServer) Bukkit.getServer())
|
WritableRegistry<Biome> biomeRegistry = (WritableRegistry<Biome>) ((CraftServer) Bukkit.getServer())
|
||||||
.getServer()
|
.getServer()
|
||||||
.registryAccess()
|
.registryAccess()
|
||||||
.ownedRegistryOrThrow(
|
.registryOrThrow(BIOME);
|
||||||
Registry.BIOME_REGISTRY);
|
|
||||||
List<ResourceLocation> keys = biomeRegistry.stream()
|
List<ResourceLocation> keys = biomeRegistry.stream()
|
||||||
.map(biomeRegistry::getKey).filter(Objects::nonNull).toList();
|
.map(biomeRegistry::getKey).filter(Objects::nonNull).toList();
|
||||||
List<NamespacedKey> namespacedKeys = new ArrayList<>();
|
List<NamespacedKey> namespacedKeys = new ArrayList<>();
|
||||||
@ -659,4 +624,16 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
|||||||
return new PaperweightPostProcessor();
|
return new PaperweightPostProcessor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean wasAccessibleSinceLastSave(ChunkHolder holder) {
|
||||||
|
if (!PaperLib.isPaper() || !PaperweightPlatformAdapter.POST_CHUNK_REWRITE) {
|
||||||
|
try {
|
||||||
|
return (boolean) CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE.invoke(holder);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException ignored) {
|
||||||
|
// fall-through
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Papers new chunk system has no related replacement - therefor we assume true.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.Fawe;
|
import com.fastasyncworldedit.core.Fawe;
|
||||||
import com.fastasyncworldedit.core.math.IntPair;
|
import com.fastasyncworldedit.core.math.IntPair;
|
||||||
@ -15,14 +15,15 @@ import net.minecraft.core.BlockPos;
|
|||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.level.ChunkHolder;
|
import net.minecraft.server.dedicated.DedicatedServer;
|
||||||
import net.minecraft.server.level.ServerChunkCache;
|
import net.minecraft.server.level.ServerChunkCache;
|
||||||
|
import net.minecraft.server.level.FullChunkStatus;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
import org.bukkit.craftbukkit.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData;
|
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -102,7 +103,7 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess<Level
|
|||||||
}
|
}
|
||||||
// Since FAWE is.. Async we need to do it on the main thread (wooooo.. :( )
|
// Since FAWE is.. Async we need to do it on the main thread (wooooo.. :( )
|
||||||
cachedChanges.add(new CachedChange(levelChunk, blockPos, blockState));
|
cachedChanges.add(new CachedChange(levelChunk, blockPos, blockState));
|
||||||
cachedChunksToSend.add(new IntPair(levelChunk.bukkitChunk.getX(), levelChunk.bukkitChunk.getZ()));
|
cachedChunksToSend.add(new IntPair(levelChunk.locX, levelChunk.locZ));
|
||||||
boolean nextTick = lastTick.get() > currentTick;
|
boolean nextTick = lastTick.get() > currentTick;
|
||||||
if (nextTick || cachedChanges.size() >= 1024) {
|
if (nextTick || cachedChanges.size() >= 1024) {
|
||||||
if (nextTick) {
|
if (nextTick) {
|
||||||
@ -140,7 +141,7 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess<Level
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
net.minecraft.nbt.Tag nativeTag = paperweightFaweAdapter.fromNativeBinary(tag);
|
net.minecraft.nbt.Tag nativeTag = paperweightFaweAdapter.fromNativeBinary(tag);
|
||||||
blockEntity.load((CompoundTag) nativeTag);
|
blockEntity.loadWithComponents((CompoundTag) nativeTag, DedicatedServer.getServer().registryAccess());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +158,7 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess<Level
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isChunkTicking(LevelChunk levelChunk) {
|
public boolean isChunkTicking(LevelChunk levelChunk) {
|
||||||
return levelChunk.getFullStatus().isOrAfter(ChunkHolder.FullChunkStatus.TICKING);
|
return levelChunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -181,7 +182,7 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess<Level
|
|||||||
// Un-nest neighbour updating
|
// Un-nest neighbour updating
|
||||||
for (Direction direction : NEIGHBOUR_ORDER) {
|
for (Direction direction : NEIGHBOUR_ORDER) {
|
||||||
BlockPos shifted = blockPos.relative(direction);
|
BlockPos shifted = blockPos.relative(direction);
|
||||||
level.getBlockState(shifted).neighborChanged(level, shifted, oldState.getBlock(), blockPos, false);
|
level.getBlockState(shifted).handleNeighborChanged(level, shifted, oldState.getBlock(), blockPos, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (newState.hasAnalogOutputSignal()) {
|
if (newState.hasAnalogOutputSignal()) {
|
@ -1,4 +1,4 @@
|
|||||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||||
|
|
||||||
import com.fastasyncworldedit.bukkit.adapter.BukkitGetBlocks;
|
import com.fastasyncworldedit.bukkit.adapter.BukkitGetBlocks;
|
||||||
import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore;
|
import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore;
|
||||||
@ -20,7 +20,7 @@ import com.sk89q.jnbt.StringTag;
|
|||||||
import com.sk89q.jnbt.Tag;
|
import com.sk89q.jnbt.Tag;
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt.PaperweightLazyCompoundTag;
|
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt.PaperweightLazyCompoundTag;
|
||||||
import com.sk89q.worldedit.internal.Constants;
|
import com.sk89q.worldedit.internal.Constants;
|
||||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
@ -29,12 +29,9 @@ import com.sk89q.worldedit.world.biome.BiomeTypes;
|
|||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import io.papermc.paper.event.block.BeaconDeactivatedEvent;
|
import io.papermc.paper.event.block.BeaconDeactivatedEvent;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.*;
|
||||||
import net.minecraft.core.Holder;
|
|
||||||
import net.minecraft.core.IdMap;
|
|
||||||
import net.minecraft.core.Registry;
|
|
||||||
import net.minecraft.core.SectionPos;
|
|
||||||
import net.minecraft.nbt.IntTag;
|
import net.minecraft.nbt.IntTag;
|
||||||
|
import net.minecraft.server.dedicated.DedicatedServer;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.sounds.SoundEvents;
|
import net.minecraft.sounds.SoundEvents;
|
||||||
import net.minecraft.util.BitStorage;
|
import net.minecraft.util.BitStorage;
|
||||||
@ -46,33 +43,17 @@ import net.minecraft.world.level.biome.Biome;
|
|||||||
import net.minecraft.world.level.block.entity.BeaconBlockEntity;
|
import net.minecraft.world.level.block.entity.BeaconBlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.chunk.DataLayer;
|
import net.minecraft.world.level.chunk.*;
|
||||||
import net.minecraft.world.level.chunk.HashMapPalette;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
|
||||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
|
||||||
import net.minecraft.world.level.chunk.LinearPalette;
|
|
||||||
import net.minecraft.world.level.chunk.Palette;
|
|
||||||
import net.minecraft.world.level.chunk.PalettedContainer;
|
|
||||||
import net.minecraft.world.level.levelgen.Heightmap;
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
import org.bukkit.craftbukkit.CraftWorld;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.block.CraftBlock;
|
import org.bukkit.craftbukkit.block.CraftBlock;
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.AbstractSet;
|
import java.util.*;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
@ -83,13 +64,16 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static net.minecraft.core.registries.Registries.BIOME;
|
||||||
|
|
||||||
public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBlocks {
|
public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBlocks {
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||||
|
|
||||||
private static final Function<BlockPos, BlockVector3> posNms2We = v -> BlockVector3.at(v.getX(), v.getY(), v.getZ());
|
private static final Function<BlockPos, BlockVector3> posNms2We = v -> BlockVector3.at(v.getX(), v.getY(), v.getZ());
|
||||||
private static final Function<BlockEntity, CompoundTag> nmsTile2We =
|
private static final Function<BlockEntity, CompoundTag> nmsTile2We = tileEntity -> new PaperweightLazyCompoundTag(
|
||||||
tileEntity -> new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId));
|
Suppliers.memoize(() -> tileEntity.saveWithId(DedicatedServer.getServer().registryAccess()))
|
||||||
|
);
|
||||||
private final PaperweightFaweAdapter adapter = ((PaperweightFaweAdapter) WorldEditPlugin
|
private final PaperweightFaweAdapter adapter = ((PaperweightFaweAdapter) WorldEditPlugin
|
||||||
.getInstance()
|
.getInstance()
|
||||||
.getBukkitImplAdapter());
|
.getBukkitImplAdapter());
|
||||||
@ -130,7 +114,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
this.maxSectionPosition = maxHeight >> 4;
|
this.maxSectionPosition = maxHeight >> 4;
|
||||||
this.skyLight = new DataLayer[getSectionCount()];
|
this.skyLight = new DataLayer[getSectionCount()];
|
||||||
this.blockLight = new DataLayer[getSectionCount()];
|
this.blockLight = new DataLayer[getSectionCount()];
|
||||||
this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
|
this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(BIOME);
|
||||||
this.biomeHolderIdMap = biomeRegistry.asHolderIdMap();
|
this.biomeHolderIdMap = biomeRegistry.asHolderIdMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,7 +244,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
if (blockEntity == null) {
|
if (blockEntity == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId));
|
return new PaperweightLazyCompoundTag(Suppliers.memoize(() -> blockEntity.saveWithId(DedicatedServer.getServer().registryAccess())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -289,8 +273,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(
|
((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(
|
||||||
LightLayer.BLOCK,
|
LightLayer.BLOCK,
|
||||||
sectionPos,
|
sectionPos,
|
||||||
dataLayer,
|
dataLayer
|
||||||
true
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
skyLight[alayer] = dataLayer;
|
skyLight[alayer] = dataLayer;
|
||||||
@ -317,7 +300,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
Arrays.fill(LAYER_COUNT, (byte) 15);
|
Arrays.fill(LAYER_COUNT, (byte) 15);
|
||||||
dataLayer = new DataLayer(LAYER_COUNT);
|
dataLayer = new DataLayer(LAYER_COUNT);
|
||||||
((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(LightLayer.BLOCK, sectionPos,
|
((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(LightLayer.BLOCK, sectionPos,
|
||||||
dataLayer, true
|
dataLayer
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
blockLight[alayer] = dataLayer;
|
blockLight[alayer] = dataLayer;
|
||||||
@ -334,7 +317,15 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag getEntity(UUID uuid) {
|
public CompoundTag getEntity(UUID uuid) {
|
||||||
Entity entity = serverLevel.getEntity(uuid);
|
ensureLoaded(serverLevel, chunkX, chunkZ);
|
||||||
|
List<Entity> entities = PaperweightPlatformAdapter.getEntities(getChunk());
|
||||||
|
Entity entity = null;
|
||||||
|
for (Entity e : entities) {
|
||||||
|
if (e.getUUID().equals(uuid)) {
|
||||||
|
entity = e;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity();
|
org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity();
|
||||||
return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData();
|
return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData();
|
||||||
@ -349,6 +340,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<CompoundTag> getEntities() {
|
public Set<CompoundTag> getEntities() {
|
||||||
|
ensureLoaded(serverLevel, chunkX, chunkZ);
|
||||||
List<Entity> entities = PaperweightPlatformAdapter.getEntities(getChunk());
|
List<Entity> entities = PaperweightPlatformAdapter.getEntities(getChunk());
|
||||||
if (entities.isEmpty()) {
|
if (entities.isEmpty()) {
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
@ -385,7 +377,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
public Iterator<CompoundTag> iterator() {
|
public Iterator<CompoundTag> iterator() {
|
||||||
Iterable<CompoundTag> result = entities.stream().map(input -> {
|
Iterable<CompoundTag> result = entities.stream().map(input -> {
|
||||||
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
|
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
|
||||||
PaperweightPlatformAdapter.readEntityIntoTag(input, tag);
|
input.save(tag);
|
||||||
return (CompoundTag) adapter.toNative(tag);
|
return (CompoundTag) adapter.toNative(tag);
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
return result.iterator();
|
return result.iterator();
|
||||||
@ -474,7 +466,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
synchronized (super.sectionLocks[getSectionIndex]) {
|
synchronized (super.sectionLocks[getSectionIndex]) {
|
||||||
LevelChunkSection existingSection = levelChunkSections[getSectionIndex];
|
LevelChunkSection existingSection = levelChunkSections[getSectionIndex];
|
||||||
if (createCopy && existingSection != null) {
|
if (createCopy && existingSection != null) {
|
||||||
copy.storeBiomes(getSectionIndex, existingSection.getBiomes().copy());
|
copy.storeBiomes(getSectionIndex, existingSection.getBiomes());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (existingSection == null) {
|
if (existingSection == null) {
|
||||||
@ -507,8 +499,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PalettedContainer<Holder<Biome>> biomeData = existingSection.getBiomes();
|
setBiomesToPalettedContainer(biomes, setSectionIndex, existingSection.getBiomes());
|
||||||
setBiomesToPalettedContainer(biomes[setSectionIndex], biomeData);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -543,7 +534,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
System.arraycopy(tmpLoad, 0, copyArr, 0, 4096);
|
System.arraycopy(tmpLoad, 0, copyArr, 0, 4096);
|
||||||
copy.storeSection(getSectionIndex, copyArr);
|
copy.storeSection(getSectionIndex, copyArr);
|
||||||
if (biomes != null && existingSection != null) {
|
if (biomes != null && existingSection != null) {
|
||||||
copy.storeBiomes(getSectionIndex, existingSection.getBiomes().copy());
|
copy.storeBiomes(getSectionIndex, existingSection.getBiomes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,8 +546,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
.getBukkitImplAdapter()
|
.getBukkitImplAdapter()
|
||||||
.getInternalBiomeId(
|
.getInternalBiomeId(
|
||||||
BiomeTypes.PLAINS)),
|
BiomeTypes.PLAINS)),
|
||||||
PalettedContainer.Strategy.SECTION_BIOMES,
|
PalettedContainer.Strategy.SECTION_BIOMES
|
||||||
null
|
|
||||||
) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap);
|
) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap);
|
||||||
newSection = PaperweightPlatformAdapter.newChunkSection(
|
newSection = PaperweightPlatformAdapter.newChunkSection(
|
||||||
layerNo,
|
layerNo,
|
||||||
@ -616,11 +606,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
sectionLock.writeLock().unlock();
|
sectionLock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
PalettedContainer<Holder<Biome>> biomeData = existingSection.getBiomes();
|
PalettedContainer<Holder<Biome>> biomeData = setBiomesToPalettedContainer(
|
||||||
|
biomes,
|
||||||
if (biomes != null && biomes[setSectionIndex] != null) {
|
setSectionIndex,
|
||||||
setBiomesToPalettedContainer(biomes[setSectionIndex], biomeData);
|
existingSection.getBiomes()
|
||||||
}
|
);
|
||||||
|
|
||||||
newSection =
|
newSection =
|
||||||
PaperweightPlatformAdapter.newChunkSection(
|
PaperweightPlatformAdapter.newChunkSection(
|
||||||
@ -705,7 +695,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
}
|
}
|
||||||
if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) {
|
if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) {
|
||||||
for (UUID uuid : entityRemoves) {
|
for (UUID uuid : entityRemoves) {
|
||||||
Entity entity = nmsWorld.entityManager.getEntityGetter().get(uuid);
|
Entity entity = nmsWorld.getEntities().get(uuid);
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
removeEntity(entity);
|
removeEntity(entity);
|
||||||
}
|
}
|
||||||
@ -800,7 +790,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
tag.put("x", IntTag.valueOf(x));
|
tag.put("x", IntTag.valueOf(x));
|
||||||
tag.put("y", IntTag.valueOf(y));
|
tag.put("y", IntTag.valueOf(y));
|
||||||
tag.put("z", IntTag.valueOf(z));
|
tag.put("z", IntTag.valueOf(z));
|
||||||
tileEntity.load(tag);
|
tileEntity.loadWithComponents(tag, DedicatedServer.getServer().registryAccess());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1076,8 +1066,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(
|
((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(
|
||||||
lightLayer,
|
lightLayer,
|
||||||
sectionPos,
|
sectionPos,
|
||||||
dataLayer,
|
dataLayer
|
||||||
true
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
synchronized (dataLayer) {
|
synchronized (dataLayer) {
|
||||||
@ -1095,22 +1084,35 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setBiomesToPalettedContainer(
|
private PalettedContainer<Holder<Biome>> setBiomesToPalettedContainer(
|
||||||
final BiomeType[] biomes,
|
final BiomeType[][] biomes,
|
||||||
PalettedContainer<Holder<Biome>> data
|
final int sectionIndex,
|
||||||
|
final PalettedContainerRO<Holder<Biome>> data
|
||||||
) {
|
) {
|
||||||
int index = 0;
|
PalettedContainer<Holder<Biome>> biomeData;
|
||||||
if (biomes == null) {
|
if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
|
||||||
return;
|
biomeData = palettedContainer;
|
||||||
|
} else {
|
||||||
|
LOGGER.warn(
|
||||||
|
"Cannot correctly set biomes to world, existing biomes may be lost. Expected class " +
|
||||||
|
"type {} but got {}",
|
||||||
|
PalettedContainer.class.getSimpleName(),
|
||||||
|
data.getClass().getSimpleName()
|
||||||
|
);
|
||||||
|
biomeData = data.recreate();
|
||||||
}
|
}
|
||||||
for (int y = 0; y < 4; y++) {
|
BiomeType[] sectionBiomes;
|
||||||
|
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
|
||||||
|
return biomeData;
|
||||||
|
}
|
||||||
|
for (int y = 0, index = 0; y < 4; y++) {
|
||||||
for (int z = 0; z < 4; z++) {
|
for (int z = 0; z < 4; z++) {
|
||||||
for (int x = 0; x < 4; x++, index++) {
|
for (int x = 0; x < 4; x++, index++) {
|
||||||
BiomeType biomeType = biomes[index];
|
BiomeType biomeType = sectionBiomes[index];
|
||||||
if (biomeType == null) {
|
if (biomeType == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
data.set(
|
biomeData.set(
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
z,
|
z,
|
||||||
@ -1122,6 +1124,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return biomeData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -1,4 +1,4 @@
|
|||||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||||
import com.fastasyncworldedit.core.queue.IBlocks;
|
import com.fastasyncworldedit.core.queue.IBlocks;
|
||||||
@ -8,19 +8,23 @@ import com.google.common.base.Suppliers;
|
|||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt.PaperweightLazyCompoundTag;
|
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt.PaperweightLazyCompoundTag;
|
||||||
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.server.dedicated.DedicatedServer;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import net.minecraft.world.level.chunk.PalettedContainer;
|
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||||
|
import net.minecraft.world.level.chunk.PalettedContainerRO;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -33,6 +37,8 @@ import java.util.concurrent.Future;
|
|||||||
|
|
||||||
public class PaperweightGetBlocks_Copy implements IChunkGet {
|
public class PaperweightGetBlocks_Copy implements IChunkGet {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||||
|
|
||||||
private final Map<BlockVector3, CompoundTag> tiles = new HashMap<>();
|
private final Map<BlockVector3, CompoundTag> tiles = new HashMap<>();
|
||||||
private final Set<CompoundTag> entities = new HashSet<>();
|
private final Set<CompoundTag> entities = new HashSet<>();
|
||||||
private final char[][] blocks;
|
private final char[][] blocks;
|
||||||
@ -57,7 +63,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
|
|||||||
blockEntity.getBlockPos().getY(),
|
blockEntity.getBlockPos().getY(),
|
||||||
blockEntity.getBlockPos().getZ()
|
blockEntity.getBlockPos().getZ()
|
||||||
),
|
),
|
||||||
new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId))
|
new PaperweightLazyCompoundTag(Suppliers.memoize(() -> blockEntity.saveWithId(DedicatedServer.getServer().registryAccess())))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +82,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
|
|||||||
protected void storeEntity(Entity entity) {
|
protected void storeEntity(Entity entity) {
|
||||||
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
|
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
|
||||||
net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag();
|
net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag();
|
||||||
PaperweightPlatformAdapter.readEntityIntoTag(entity, compoundTag);
|
entity.save(compoundTag);
|
||||||
entities.add((CompoundTag) adapter.toNative(compoundTag));
|
entities.add((CompoundTag) adapter.toNative(compoundTag));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,11 +172,19 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
|
|||||||
blocks[layer] = data;
|
blocks[layer] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void storeBiomes(int layer, PalettedContainer<Holder<Biome>> biomeData) {
|
protected void storeBiomes(int layer, PalettedContainerRO<Holder<Biome>> biomeData) {
|
||||||
if (biomes == null) {
|
if (biomes == null) {
|
||||||
biomes = new PalettedContainer[getSectionCount()];
|
biomes = new PalettedContainer[getSectionCount()];
|
||||||
}
|
}
|
||||||
biomes[layer] = biomeData;
|
if (biomeData instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
|
||||||
|
biomes[layer] = palettedContainer.copy();
|
||||||
|
} else {
|
||||||
|
LOGGER.error(
|
||||||
|
"Cannot correctly save biomes to history. Expected class type {} but got {}",
|
||||||
|
PalettedContainer.class.getSimpleName(),
|
||||||
|
biomeData.getClass().getSimpleName()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -1,4 +1,4 @@
|
|||||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||||
|
|
||||||
import com.fastasyncworldedit.bukkit.adapter.MapChunkUtil;
|
import com.fastasyncworldedit.bukkit.adapter.MapChunkUtil;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||||
@ -10,10 +10,10 @@ public class PaperweightMapChunkUtil extends MapChunkUtil<ClientboundLevelChunkW
|
|||||||
|
|
||||||
public PaperweightMapChunkUtil() throws NoSuchFieldException {
|
public PaperweightMapChunkUtil() throws NoSuchFieldException {
|
||||||
fieldX = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("TWO_MEGABYTES", "a"));
|
fieldX = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("TWO_MEGABYTES", "a"));
|
||||||
fieldZ = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("x", "a"));
|
fieldZ = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("x", "b"));
|
||||||
fieldBitMask = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("z", "b"));
|
fieldBitMask = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("z", "c"));
|
||||||
fieldHeightMap = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("heightmaps", "b"));
|
fieldHeightMap = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("heightmaps", "b"));
|
||||||
fieldChunkData = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("chunkData", "c"));
|
fieldChunkData = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("chunkData", "d"));
|
||||||
fieldBlockEntities = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("buffer", "c"));
|
fieldBlockEntities = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("buffer", "c"));
|
||||||
fieldFull = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("blockEntitiesData", "d"));
|
fieldFull = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("blockEntitiesData", "d"));
|
||||||
fieldX.setAccessible(true);
|
fieldX.setAccessible(true);
|
@ -1,5 +1,6 @@
|
|||||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||||
|
|
||||||
|
import com.destroystokyo.paper.util.maplist.EntityList;
|
||||||
import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter;
|
import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter;
|
||||||
import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore;
|
import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore;
|
||||||
import com.fastasyncworldedit.bukkit.adapter.NMSAdapter;
|
import com.fastasyncworldedit.bukkit.adapter.NMSAdapter;
|
||||||
@ -19,6 +20,7 @@ import com.sk89q.worldedit.world.biome.BiomeTypes;
|
|||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
|
import io.papermc.paper.world.ChunkEntitySlices;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.IdMap;
|
import net.minecraft.core.IdMap;
|
||||||
@ -30,19 +32,19 @@ import net.minecraft.server.level.ServerLevel;
|
|||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.server.level.TicketType;
|
import net.minecraft.server.level.TicketType;
|
||||||
import net.minecraft.util.BitStorage;
|
import net.minecraft.util.BitStorage;
|
||||||
|
import net.minecraft.util.ExceptionCollector;
|
||||||
import net.minecraft.util.SimpleBitStorage;
|
import net.minecraft.util.SimpleBitStorage;
|
||||||
import net.minecraft.util.ThreadingDetector;
|
import net.minecraft.util.ThreadingDetector;
|
||||||
import net.minecraft.util.Unit;
|
import net.minecraft.util.Unit;
|
||||||
import net.minecraft.util.ZeroBitStorage;
|
import net.minecraft.util.ZeroBitStorage;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.npc.AbstractVillager;
|
|
||||||
import net.minecraft.world.item.trading.MerchantOffers;
|
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.GlobalPalette;
|
import net.minecraft.world.level.chunk.GlobalPalette;
|
||||||
import net.minecraft.world.level.chunk.HashMapPalette;
|
import net.minecraft.world.level.chunk.HashMapPalette;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
@ -51,15 +53,17 @@ import net.minecraft.world.level.chunk.LinearPalette;
|
|||||||
import net.minecraft.world.level.chunk.Palette;
|
import net.minecraft.world.level.chunk.Palette;
|
||||||
import net.minecraft.world.level.chunk.PalettedContainer;
|
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||||
import net.minecraft.world.level.chunk.SingleValuePalette;
|
import net.minecraft.world.level.chunk.SingleValuePalette;
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
import net.minecraft.world.level.entity.PersistentEntitySectionManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftChunk;
|
import org.bukkit.craftbukkit.CraftChunk;
|
||||||
import sun.misc.Unsafe;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
@ -79,6 +83,9 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import static java.lang.invoke.MethodType.methodType;
|
||||||
|
import static net.minecraft.core.registries.Registries.BIOME;
|
||||||
|
|
||||||
public final class PaperweightPlatformAdapter extends NMSAdapter {
|
public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||||
|
|
||||||
public static final Field fieldData;
|
public static final Field fieldData;
|
||||||
@ -100,14 +107,23 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
private static final MethodHandle methodRemoveGameEventListener;
|
private static final MethodHandle methodRemoveGameEventListener;
|
||||||
private static final MethodHandle methodremoveTickingBlockEntity;
|
private static final MethodHandle methodremoveTickingBlockEntity;
|
||||||
|
|
||||||
private static final Field fieldOffers;
|
/*
|
||||||
private static final MerchantOffers OFFERS = new MerchantOffers();
|
* This is a workaround for the changes from https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/commits/1fddefce1cdce44010927b888432bf70c0e88cde#src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||||
|
* and is only needed to support 1.19.4 versions before *and* after this change.
|
||||||
|
*/
|
||||||
|
private static final MethodHandle CRAFT_CHUNK_GET_HANDLE;
|
||||||
|
|
||||||
private static final Field fieldRemove;
|
private static final Field fieldRemove;
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||||
|
|
||||||
|
static final boolean POST_CHUNK_REWRITE;
|
||||||
|
private static Method PAPER_CHUNK_GEN_ALL_ENTITIES;
|
||||||
|
private static Field LEVEL_CHUNK_ENTITIES;
|
||||||
|
private static Field SERVER_LEVEL_ENTITY_MANAGER;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
final MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||||
try {
|
try {
|
||||||
fieldData = PalettedContainer.class.getDeclaredField(Refraction.pickName("data", "d"));
|
fieldData = PalettedContainer.class.getDeclaredField(Refraction.pickName("data", "d"));
|
||||||
fieldData.setAccessible(true);
|
fieldData.setAccessible(true);
|
||||||
@ -121,11 +137,11 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
fieldPalette = dataClazz.getDeclaredField(Refraction.pickName("palette", "c"));
|
fieldPalette = dataClazz.getDeclaredField(Refraction.pickName("palette", "c"));
|
||||||
fieldPalette.setAccessible(true);
|
fieldPalette.setAccessible(true);
|
||||||
|
|
||||||
fieldTickingFluidCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingFluidCount", "h"));
|
fieldTickingFluidCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingFluidCount", "g"));
|
||||||
fieldTickingFluidCount.setAccessible(true);
|
fieldTickingFluidCount.setAccessible(true);
|
||||||
fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "g"));
|
fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f"));
|
||||||
fieldTickingBlockCount.setAccessible(true);
|
fieldTickingBlockCount.setAccessible(true);
|
||||||
fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "f"));
|
fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "e"));
|
||||||
fieldNonEmptyBlockCount.setAccessible(true);
|
fieldNonEmptyBlockCount.setAccessible(true);
|
||||||
|
|
||||||
Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName(
|
Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName(
|
||||||
@ -133,7 +149,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
"b"
|
"b"
|
||||||
), long.class);
|
), long.class);
|
||||||
getVisibleChunkIfPresent.setAccessible(true);
|
getVisibleChunkIfPresent.setAccessible(true);
|
||||||
methodGetVisibleChunk = MethodHandles.lookup().unreflect(getVisibleChunkIfPresent);
|
methodGetVisibleChunk = lookup.unreflect(getVisibleChunkIfPresent);
|
||||||
|
|
||||||
if (!PaperLib.isPaper()) {
|
if (!PaperLib.isPaper()) {
|
||||||
fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f"));
|
fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f"));
|
||||||
@ -147,31 +163,66 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Method removeGameEventListener = LevelChunk.class.getDeclaredMethod(
|
Method removeGameEventListener = LevelChunk.class.getDeclaredMethod(
|
||||||
Refraction.pickName("removeGameEventListener", "d"),
|
Refraction.pickName("removeGameEventListener", "a"),
|
||||||
BlockEntity.class
|
BlockEntity.class,
|
||||||
|
ServerLevel.class
|
||||||
);
|
);
|
||||||
removeGameEventListener.setAccessible(true);
|
removeGameEventListener.setAccessible(true);
|
||||||
methodRemoveGameEventListener = MethodHandles.lookup().unreflect(removeGameEventListener);
|
methodRemoveGameEventListener = lookup.unreflect(removeGameEventListener);
|
||||||
|
|
||||||
Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod(
|
Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod(
|
||||||
Refraction.pickName(
|
Refraction.pickName(
|
||||||
"removeBlockEntityTicker",
|
"removeBlockEntityTicker",
|
||||||
"l"
|
"k"
|
||||||
), BlockPos.class
|
), BlockPos.class
|
||||||
);
|
);
|
||||||
removeBlockEntityTicker.setAccessible(true);
|
removeBlockEntityTicker.setAccessible(true);
|
||||||
methodremoveTickingBlockEntity = MethodHandles.lookup().unreflect(removeBlockEntityTicker);
|
methodremoveTickingBlockEntity = lookup.unreflect(removeBlockEntityTicker);
|
||||||
|
|
||||||
fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "p"));
|
fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "p"));
|
||||||
fieldRemove.setAccessible(true);
|
fieldRemove.setAccessible(true);
|
||||||
|
|
||||||
fieldOffers = AbstractVillager.class.getDeclaredField(Refraction.pickName("offers", "bW"));
|
boolean chunkRewrite;
|
||||||
fieldOffers.setAccessible(true);
|
try {
|
||||||
} catch (RuntimeException e) {
|
ServerLevel.class.getDeclaredMethod("getEntityLookup");
|
||||||
throw e;
|
chunkRewrite = true;
|
||||||
} catch (Throwable rethrow) {
|
PAPER_CHUNK_GEN_ALL_ENTITIES = ChunkEntitySlices.class.getDeclaredMethod("getAllEntities");
|
||||||
rethrow.printStackTrace();
|
PAPER_CHUNK_GEN_ALL_ENTITIES.setAccessible(true);
|
||||||
throw new RuntimeException(rethrow);
|
} catch (NoSuchMethodException ignored) {
|
||||||
|
chunkRewrite = false;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
// Paper - Pre-Chunk-Update
|
||||||
|
LEVEL_CHUNK_ENTITIES = LevelChunk.class.getDeclaredField("entities");
|
||||||
|
LEVEL_CHUNK_ENTITIES.setAccessible(true);
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// Non-Paper
|
||||||
|
SERVER_LEVEL_ENTITY_MANAGER = ServerLevel.class.getDeclaredField(Refraction.pickName("entityManager", "N"));
|
||||||
|
SERVER_LEVEL_ENTITY_MANAGER.setAccessible(true);
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
POST_CHUNK_REWRITE = chunkRewrite;
|
||||||
|
} catch (RuntimeException | Error e) {
|
||||||
|
throw e;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
MethodHandle craftChunkGetHandle;
|
||||||
|
final MethodType type = methodType(LevelChunk.class);
|
||||||
|
try {
|
||||||
|
craftChunkGetHandle = lookup.findVirtual(CraftChunk.class, "getHandle", type);
|
||||||
|
} catch (NoSuchMethodException | IllegalAccessException e) {
|
||||||
|
try {
|
||||||
|
final MethodType newType = methodType(ChunkAccess.class, ChunkStatus.class);
|
||||||
|
craftChunkGetHandle = lookup.findVirtual(CraftChunk.class, "getHandle", newType);
|
||||||
|
craftChunkGetHandle = MethodHandles.insertArguments(craftChunkGetHandle, 1, ChunkStatus.FULL);
|
||||||
|
} catch (NoSuchMethodException | IllegalAccessException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CRAFT_CHUNK_GET_HANDLE = craftChunkGetHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean setSectionAtomic(
|
static boolean setSectionAtomic(
|
||||||
@ -255,7 +306,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
throw new UnsupportedOperationException("Cannot load chunk from unloaded world " + world + "!");
|
throw new UnsupportedOperationException("Cannot load chunk from unloaded world " + world + "!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return chunk.getHandle();
|
addTicket(serverLevel, chunkX, chunkZ);
|
||||||
|
return (LevelChunk) CRAFT_CHUNK_GET_HANDLE.invoke(chunk);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -265,9 +317,9 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
|
|
||||||
private static void addTicket(ServerLevel serverLevel, int chunkX, int chunkZ) {
|
private static void addTicket(ServerLevel serverLevel, int chunkX, int chunkZ) {
|
||||||
// Ensure chunk is definitely loaded before applying a ticket
|
// Ensure chunk is definitely loaded before applying a ticket
|
||||||
net.minecraft.server.MCUtil.MAIN_EXECUTOR.execute(() -> serverLevel
|
io.papermc.paper.util.MCUtil.MAIN_EXECUTOR.execute(() -> serverLevel
|
||||||
.getChunkSource()
|
.getChunkSource()
|
||||||
.addRegionTicket(TicketType.PLUGIN, new ChunkPos(chunkX, chunkZ), 0, Unit.INSTANCE));
|
.addRegionTicket(TicketType.UNLOAD_COOLDOWN, new ChunkPos(chunkX, chunkZ), 0, Unit.INSTANCE));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChunkHolder getPlayerChunk(ServerLevel nmsWorld, final int chunkX, final int chunkZ) {
|
public static ChunkHolder getPlayerChunk(ServerLevel nmsWorld, final int chunkX, final int chunkZ) {
|
||||||
@ -286,20 +338,21 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ);
|
ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ);
|
||||||
// UNLOADED_CHUNK
|
LevelChunk levelChunk;
|
||||||
Optional<LevelChunk> optional = ((Either) chunkHolder
|
|
||||||
.getTickingChunkFuture()
|
|
||||||
.getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left();
|
|
||||||
if (PaperLib.isPaper()) {
|
if (PaperLib.isPaper()) {
|
||||||
// getChunkAtIfLoadedImmediately is paper only
|
// getChunkAtIfLoadedImmediately is paper only
|
||||||
optional = optional.or(() -> Optional.ofNullable(nmsWorld
|
levelChunk = nmsWorld
|
||||||
.getChunkSource()
|
.getChunkSource()
|
||||||
.getChunkAtIfLoadedImmediately(chunkX, chunkZ)));
|
.getChunkAtIfLoadedImmediately(chunkX, chunkZ);
|
||||||
|
} else {
|
||||||
|
levelChunk = ((Optional<LevelChunk>) ((Either) chunkHolder
|
||||||
|
.getTickingChunkFuture() // method is not present with new paper chunk system
|
||||||
|
.getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left())
|
||||||
|
.orElse(null);
|
||||||
}
|
}
|
||||||
if (optional.isEmpty()) {
|
if (levelChunk == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LevelChunk levelChunk = optional.get();
|
|
||||||
TaskManager.taskManager().task(() -> {
|
TaskManager.taskManager().task(() -> {
|
||||||
ClientboundLevelChunkWithLightPacket packet;
|
ClientboundLevelChunkWithLightPacket packet;
|
||||||
if (PaperLib.isPaper()) {
|
if (PaperLib.isPaper()) {
|
||||||
@ -307,9 +360,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
levelChunk,
|
levelChunk,
|
||||||
nmsWorld.getChunkSource().getLightEngine(),
|
nmsWorld.getChunkSource().getLightEngine(),
|
||||||
null,
|
null,
|
||||||
null,
|
null
|
||||||
true,
|
// last false is to not bother with x-ray
|
||||||
false // last false is to not bother with x-ray
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// deprecated on paper - deprecation suppressed
|
// deprecated on paper - deprecation suppressed
|
||||||
@ -317,8 +369,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
levelChunk,
|
levelChunk,
|
||||||
nmsWorld.getChunkSource().getLightEngine(),
|
nmsWorld.getChunkSource().getLightEngine(),
|
||||||
null,
|
null,
|
||||||
null,
|
null
|
||||||
true
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
|
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
|
||||||
@ -424,12 +475,11 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
.getBukkitImplAdapter()
|
.getBukkitImplAdapter()
|
||||||
.getInternalBiomeId(
|
.getInternalBiomeId(
|
||||||
BiomeTypes.PLAINS)),
|
BiomeTypes.PLAINS)),
|
||||||
PalettedContainer.Strategy.SECTION_BIOMES,
|
PalettedContainer.Strategy.SECTION_BIOMES
|
||||||
null
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new LevelChunkSection(layer, blockStatePalettedContainer, biomes);
|
return new LevelChunkSection(blockStatePalettedContainer, biomes);
|
||||||
} catch (final Throwable e) {
|
} catch (final Throwable e) {
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
@ -447,15 +497,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
@Nullable PalettedContainer<Holder<Biome>> biomes
|
@Nullable PalettedContainer<Holder<Biome>> biomes
|
||||||
) {
|
) {
|
||||||
if (biomes == null) {
|
if (biomes == null) {
|
||||||
return new LevelChunkSection(layer, biomeRegistry);
|
return new LevelChunkSection(biomeRegistry);
|
||||||
}
|
}
|
||||||
PalettedContainer<net.minecraft.world.level.block.state.BlockState> dataPaletteBlocks = new PalettedContainer<>(
|
PalettedContainer<net.minecraft.world.level.block.state.BlockState> dataPaletteBlocks = new PalettedContainer<>(
|
||||||
Block.BLOCK_STATE_REGISTRY,
|
Block.BLOCK_STATE_REGISTRY,
|
||||||
Blocks.AIR.defaultBlockState(),
|
Blocks.AIR.defaultBlockState(),
|
||||||
PalettedContainer.Strategy.SECTION_STATES,
|
PalettedContainer.Strategy.SECTION_STATES
|
||||||
null
|
|
||||||
);
|
);
|
||||||
return new LevelChunkSection(layer, dataPaletteBlocks, biomes);
|
return new LevelChunkSection(dataPaletteBlocks, biomes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -492,8 +541,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
PalettedContainer<Holder<Biome>> biomePalettedContainer = new PalettedContainer<>(
|
PalettedContainer<Holder<Biome>> biomePalettedContainer = new PalettedContainer<>(
|
||||||
biomeRegistry,
|
biomeRegistry,
|
||||||
biomeRegistry.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)),
|
biomeRegistry.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)),
|
||||||
PalettedContainer.Strategy.SECTION_BIOMES,
|
PalettedContainer.Strategy.SECTION_BIOMES
|
||||||
null
|
|
||||||
);
|
);
|
||||||
|
|
||||||
final Palette<Holder<Biome>> biomePalette;
|
final Palette<Holder<Biome>> biomePalette;
|
||||||
@ -571,7 +619,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static BiomeType adapt(Holder<Biome> biome, LevelAccessor levelAccessor) {
|
public static BiomeType adapt(Holder<Biome> biome, LevelAccessor levelAccessor) {
|
||||||
final Registry<Biome> biomeRegistry = levelAccessor.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY);
|
final Registry<Biome> biomeRegistry = levelAccessor.registryAccess().registryOrThrow(BIOME);
|
||||||
if (biomeRegistry.getKey(biome.value()) == null) {
|
if (biomeRegistry.getKey(biome.value()) == null) {
|
||||||
return biomeRegistry.asHolderIdMap().getId(biome) == -1 ? BiomeTypes.OCEAN
|
return biomeRegistry.asHolderIdMap().getId(biome) == -1 ? BiomeTypes.OCEAN
|
||||||
: null;
|
: null;
|
||||||
@ -581,13 +629,11 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
|
|
||||||
static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) {
|
static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) {
|
||||||
try {
|
try {
|
||||||
// Do the method ourselves to avoid trying to reflect generic method parameters
|
|
||||||
// similar to removeGameEventListener
|
|
||||||
if (levelChunk.loaded || levelChunk.level.isClientSide()) {
|
if (levelChunk.loaded || levelChunk.level.isClientSide()) {
|
||||||
BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos());
|
BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos());
|
||||||
if (blockEntity != null) {
|
if (blockEntity != null) {
|
||||||
if (!levelChunk.level.isClientSide) {
|
if (!levelChunk.level.isClientSide) {
|
||||||
methodRemoveGameEventListener.invoke(levelChunk, beacon);
|
methodRemoveGameEventListener.invoke(levelChunk, beacon, levelChunk.level);
|
||||||
}
|
}
|
||||||
fieldRemove.set(beacon, true);
|
fieldRemove.set(beacon, true);
|
||||||
}
|
}
|
||||||
@ -599,30 +645,32 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static List<Entity> getEntities(LevelChunk chunk) {
|
static List<Entity> getEntities(LevelChunk chunk) {
|
||||||
return chunk.level.entityManager.getEntities(chunk.getPos());
|
ExceptionCollector<RuntimeException> collector = new ExceptionCollector<>();
|
||||||
}
|
if (PaperLib.isPaper()) {
|
||||||
|
if (POST_CHUNK_REWRITE) {
|
||||||
public static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) {
|
|
||||||
boolean isVillager = entity instanceof AbstractVillager && !Fawe.isMainThread();
|
|
||||||
boolean unset = false;
|
|
||||||
if (isVillager) {
|
|
||||||
try {
|
try {
|
||||||
if (fieldOffers.get(entity) != null) {
|
//noinspection unchecked
|
||||||
fieldOffers.set(entity, OFFERS);
|
return (List<Entity>) PAPER_CHUNK_GEN_ALL_ENTITIES.invoke(chunk.level.getEntityLookup().getChunk(chunk.locX, chunk.locZ));
|
||||||
unset = true;
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
}
|
throw new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=true]", e);
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
throw new RuntimeException("Failed to set offers field to villager to avoid async catcher.", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entity.save(compoundTag);
|
|
||||||
if (unset) {
|
|
||||||
try {
|
try {
|
||||||
fieldOffers.set(entity, null);
|
EntityList entityList = (EntityList) LEVEL_CHUNK_ENTITIES.get(chunk);
|
||||||
|
return List.of(entityList.getRawData());
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
throw new RuntimeException("Failed to set offers field to null again on villager.", e);
|
collector.add(new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=false]", e));
|
||||||
|
// fall through
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
//noinspection unchecked
|
||||||
|
return ((PersistentEntitySectionManager<Entity>) (SERVER_LEVEL_ENTITY_MANAGER.get(chunk.level))).getEntities(chunk.getPos());
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
collector.add(new RuntimeException("Failed to lookup entities [PAPER=false]", e));
|
||||||
|
}
|
||||||
|
collector.throwIfPresent();
|
||||||
|
return List.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
record FakeIdMapBlock(int size) implements IdMap<net.minecraft.world.level.block.state.BlockState> {
|
record FakeIdMapBlock(int size) implements IdMap<net.minecraft.world.level.block.state.BlockState> {
|
@ -1,4 +1,4 @@
|
|||||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.configuration.Settings;
|
import com.fastasyncworldedit.core.configuration.Settings;
|
||||||
import com.fastasyncworldedit.core.extent.processor.ProcessorScope;
|
import com.fastasyncworldedit.core.extent.processor.ProcessorScope;
|
@ -1,14 +1,14 @@
|
|||||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||||
|
|
||||||
import com.fastasyncworldedit.bukkit.adapter.StarlightRelighter;
|
import com.fastasyncworldedit.bukkit.adapter.StarlightRelighter;
|
||||||
import com.fastasyncworldedit.core.configuration.Settings;
|
import com.fastasyncworldedit.core.configuration.Settings;
|
||||||
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
||||||
import net.minecraft.server.MCUtil;
|
import net.minecraft.server.level.ChunkMap;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.TicketType;
|
import net.minecraft.server.level.TicketType;
|
||||||
import net.minecraft.util.Unit;
|
import net.minecraft.util.Unit;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
@ -18,7 +18,7 @@ import java.util.function.IntConsumer;
|
|||||||
public class PaperweightStarlightRelighter extends StarlightRelighter<ServerLevel, ChunkPos> {
|
public class PaperweightStarlightRelighter extends StarlightRelighter<ServerLevel, ChunkPos> {
|
||||||
|
|
||||||
private static final TicketType<Unit> FAWE_TICKET = TicketType.create("fawe_ticket", (a, b) -> 0);
|
private static final TicketType<Unit> FAWE_TICKET = TicketType.create("fawe_ticket", (a, b) -> 0);
|
||||||
private static final int LIGHT_LEVEL = MCUtil.getTicketLevelFor(ChunkStatus.LIGHT);
|
private static final int LIGHT_LEVEL = ChunkMap.MAX_VIEW_DISTANCE + ChunkStatus.getDistance(ChunkStatus.LIGHT);
|
||||||
|
|
||||||
public PaperweightStarlightRelighter(ServerLevel serverLevel, IQueueExtent<?> queue) {
|
public PaperweightStarlightRelighter(ServerLevel serverLevel, IQueueExtent<?> queue) {
|
||||||
super(serverLevel, queue);
|
super(serverLevel, queue);
|
@ -1,4 +1,4 @@
|
|||||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.extent.processor.lighting.NullRelighter;
|
import com.fastasyncworldedit.core.extent.processor.lighting.NullRelighter;
|
||||||
import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode;
|
import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode;
|
||||||
@ -7,7 +7,7 @@ import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
|||||||
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
import org.bukkit.craftbukkit.CraftWorld;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt;
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt;
|
||||||
|
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.jnbt.LazyCompoundTag;
|
import com.sk89q.jnbt.LazyCompoundTag;
|
@ -1,17 +1,15 @@
|
|||||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.regen;
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.regen;
|
||||||
|
|
||||||
import com.fastasyncworldedit.bukkit.adapter.Regenerator;
|
import com.fastasyncworldedit.bukkit.adapter.Regenerator;
|
||||||
import com.fastasyncworldedit.core.Fawe;
|
import com.fastasyncworldedit.core.Fawe;
|
||||||
import com.fastasyncworldedit.core.queue.IChunkCache;
|
import com.fastasyncworldedit.core.queue.IChunkCache;
|
||||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||||
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
|
||||||
import com.fastasyncworldedit.core.util.TaskManager;
|
import com.fastasyncworldedit.core.util.TaskManager;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.mojang.datafixers.util.Either;
|
|
||||||
import com.mojang.serialization.Lifecycle;
|
import com.mojang.serialization.Lifecycle;
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.PaperweightGetBlocks;
|
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.PaperweightGetBlocks;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
@ -20,14 +18,19 @@ import com.sk89q.worldedit.world.RegenOptions;
|
|||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.data.BuiltinRegistries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.dedicated.DedicatedServer;
|
||||||
|
import net.minecraft.server.level.ChunkMap;
|
||||||
|
import net.minecraft.server.level.ChunkTaskPriorityQueueSorter.Message;
|
||||||
import net.minecraft.server.level.ServerChunkCache;
|
import net.minecraft.server.level.ServerChunkCache;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ThreadedLevelLightEngine;
|
import net.minecraft.server.level.ThreadedLevelLightEngine;
|
||||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||||
|
import net.minecraft.util.thread.ProcessorHandle;
|
||||||
|
import net.minecraft.util.thread.ProcessorMailbox;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.LevelHeightAccessor;
|
import net.minecraft.world.level.LevelHeightAccessor;
|
||||||
@ -37,31 +40,34 @@ import net.minecraft.world.level.biome.BiomeSource;
|
|||||||
import net.minecraft.world.level.biome.FixedBiomeSource;
|
import net.minecraft.world.level.biome.FixedBiomeSource;
|
||||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
import net.minecraft.world.level.chunk.ChunkGeneratorStructureState;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
import net.minecraft.world.level.chunk.UpgradeData;
|
import net.minecraft.world.level.chunk.UpgradeData;
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
import net.minecraft.world.level.chunk.status.WorldGenContext;
|
||||||
import net.minecraft.world.level.dimension.LevelStem;
|
import net.minecraft.world.level.dimension.LevelStem;
|
||||||
import net.minecraft.world.level.levelgen.FlatLevelSource;
|
import net.minecraft.world.level.levelgen.FlatLevelSource;
|
||||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
import net.minecraft.world.level.levelgen.WorldOptions;
|
||||||
import net.minecraft.world.level.levelgen.blending.BlendingData;
|
import net.minecraft.world.level.levelgen.blending.BlendingData;
|
||||||
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
|
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
|
||||||
import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement;
|
import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement;
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
||||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||||
import net.minecraft.world.level.storage.PrimaryLevelData;
|
import net.minecraft.world.level.storage.PrimaryLevelData;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftServer;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
import org.bukkit.craftbukkit.CraftServer;
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.generator.CustomChunkGenerator;
|
import org.bukkit.craftbukkit.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.generator.CustomChunkGenerator;
|
||||||
import org.bukkit.generator.BiomeProvider;
|
import org.bukkit.generator.BiomeProvider;
|
||||||
import org.bukkit.generator.BlockPopulator;
|
import org.bukkit.generator.BlockPopulator;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -74,6 +80,8 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
import java.util.function.BooleanSupplier;
|
import java.util.function.BooleanSupplier;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import static net.minecraft.core.registries.Registries.BIOME;
|
||||||
|
|
||||||
public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, LevelChunk, PaperweightRegen.ChunkStatusWrap> {
|
public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, LevelChunk, PaperweightRegen.ChunkStatusWrap> {
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||||
@ -85,6 +93,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
private static final Field generatorSettingBaseSupplierField;
|
private static final Field generatorSettingBaseSupplierField;
|
||||||
private static final Field delegateField;
|
private static final Field delegateField;
|
||||||
private static final Field chunkSourceField;
|
private static final Field chunkSourceField;
|
||||||
|
private static final Field generatorStructureStateField;
|
||||||
private static final Field ringPositionsField;
|
private static final Field ringPositionsField;
|
||||||
private static final Field hasGeneratedPositionsField;
|
private static final Field hasGeneratedPositionsField;
|
||||||
|
|
||||||
@ -96,23 +105,22 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
chunkStati.put(ChunkStatus.STRUCTURE_STARTS, Concurrency.NONE); // structure starts: uses unsynchronized maps
|
chunkStati.put(ChunkStatus.STRUCTURE_STARTS, Concurrency.NONE); // structure starts: uses unsynchronized maps
|
||||||
chunkStati.put(
|
chunkStati.put(
|
||||||
ChunkStatus.STRUCTURE_REFERENCES,
|
ChunkStatus.STRUCTURE_REFERENCES,
|
||||||
Concurrency.FULL
|
Concurrency.NONE
|
||||||
); // structure refs: radius 8, but only writes to current chunk
|
); // structure refs: radius 8, but only writes to current chunk
|
||||||
chunkStati.put(ChunkStatus.BIOMES, Concurrency.FULL); // biomes: radius 0
|
chunkStati.put(ChunkStatus.BIOMES, Concurrency.NONE); // biomes: radius 0
|
||||||
chunkStati.put(ChunkStatus.NOISE, Concurrency.RADIUS); // noise: radius 8
|
chunkStati.put(ChunkStatus.NOISE, Concurrency.RADIUS); // noise: radius 8
|
||||||
chunkStati.put(ChunkStatus.SURFACE, Concurrency.NONE); // surface: radius 0, requires NONE
|
chunkStati.put(ChunkStatus.SURFACE, Concurrency.NONE); // surface: radius 0, requires NONE
|
||||||
chunkStati.put(ChunkStatus.CARVERS, Concurrency.NONE); // carvers: radius 0, but RADIUS and FULL change results
|
chunkStati.put(ChunkStatus.CARVERS, Concurrency.NONE); // carvers: radius 0, but RADIUS and FULL change results
|
||||||
chunkStati.put(
|
|
||||||
ChunkStatus.LIQUID_CARVERS,
|
|
||||||
Concurrency.NONE
|
|
||||||
); // liquid carvers: radius 0, but RADIUS and FULL change results
|
|
||||||
chunkStati.put(ChunkStatus.FEATURES, Concurrency.NONE); // features: uses unsynchronized maps
|
chunkStati.put(ChunkStatus.FEATURES, Concurrency.NONE); // features: uses unsynchronized maps
|
||||||
|
chunkStati.put(
|
||||||
|
ChunkStatus.INITIALIZE_LIGHT,
|
||||||
|
Concurrency.FULL
|
||||||
|
); // initialize_light: radius 0
|
||||||
chunkStati.put(
|
chunkStati.put(
|
||||||
ChunkStatus.LIGHT,
|
ChunkStatus.LIGHT,
|
||||||
Concurrency.FULL
|
Concurrency.FULL
|
||||||
); // light: radius 1, but no writes to other chunks, only current chunk
|
); // light: radius 1, but no writes to other chunks, only current chunk
|
||||||
chunkStati.put(ChunkStatus.SPAWN, Concurrency.FULL); // spawn: radius 0
|
chunkStati.put(ChunkStatus.SPAWN, Concurrency.NONE); // spawn: radius 0
|
||||||
chunkStati.put(ChunkStatus.HEIGHTMAPS, Concurrency.FULL); // heightmaps: radius 0
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
serverWorldsField = CraftServer.class.getDeclaredField("worlds");
|
serverWorldsField = CraftServer.class.getDeclaredField("worlds");
|
||||||
@ -134,22 +142,27 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
flatBedrockField = tmpFlatBedrockField;
|
flatBedrockField = tmpFlatBedrockField;
|
||||||
|
|
||||||
generatorSettingBaseSupplierField = NoiseBasedChunkGenerator.class.getDeclaredField(Refraction.pickName(
|
generatorSettingBaseSupplierField = NoiseBasedChunkGenerator.class.getDeclaredField(Refraction.pickName(
|
||||||
"settings", "h"));
|
"settings", "e"));
|
||||||
generatorSettingBaseSupplierField.setAccessible(true);
|
generatorSettingBaseSupplierField.setAccessible(true);
|
||||||
|
|
||||||
generatorSettingFlatField = FlatLevelSource.class.getDeclaredField(Refraction.pickName("settings", "g"));
|
generatorSettingFlatField = FlatLevelSource.class.getDeclaredField(Refraction.pickName("settings", "d"));
|
||||||
generatorSettingFlatField.setAccessible(true);
|
generatorSettingFlatField.setAccessible(true);
|
||||||
|
|
||||||
delegateField = CustomChunkGenerator.class.getDeclaredField("delegate");
|
delegateField = CustomChunkGenerator.class.getDeclaredField("delegate");
|
||||||
delegateField.setAccessible(true);
|
delegateField.setAccessible(true);
|
||||||
|
|
||||||
chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "K"));
|
chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "I"));
|
||||||
chunkSourceField.setAccessible(true);
|
chunkSourceField.setAccessible(true);
|
||||||
|
|
||||||
ringPositionsField = ChunkGenerator.class.getDeclaredField(Refraction.pickName("ringPositions", "h"));
|
generatorStructureStateField = ChunkMap.class.getDeclaredField(Refraction.pickName("chunkGeneratorState", "v"));
|
||||||
|
generatorStructureStateField.setAccessible(true);
|
||||||
|
|
||||||
|
ringPositionsField = ChunkGeneratorStructureState.class.getDeclaredField(Refraction.pickName("ringPositions", "g"));
|
||||||
ringPositionsField.setAccessible(true);
|
ringPositionsField.setAccessible(true);
|
||||||
|
|
||||||
hasGeneratedPositionsField = ChunkGenerator.class.getDeclaredField(Refraction.pickName("hasGeneratedPositions", "i"));
|
hasGeneratedPositionsField = ChunkGeneratorStructureState.class.getDeclaredField(
|
||||||
|
Refraction.pickName("hasGeneratedPositions", "h")
|
||||||
|
);
|
||||||
hasGeneratedPositionsField.setAccessible(true);
|
hasGeneratedPositionsField.setAccessible(true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
@ -162,9 +175,10 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
private ServerLevel freshWorld;
|
private ServerLevel freshWorld;
|
||||||
private ServerChunkCache freshChunkProvider;
|
private ServerChunkCache freshChunkProvider;
|
||||||
private LevelStorageSource.LevelStorageAccess session;
|
private LevelStorageSource.LevelStorageAccess session;
|
||||||
private StructureManager structureManager;
|
private StructureTemplateManager structureTemplateManager;
|
||||||
private ThreadedLevelLightEngine threadedLevelLightEngine;
|
private ThreadedLevelLightEngine threadedLevelLightEngine;
|
||||||
private ChunkGenerator chunkGenerator;
|
private ChunkGenerator chunkGenerator;
|
||||||
|
private WorldGenContext worldGenContext;
|
||||||
|
|
||||||
private Path tempDir;
|
private Path tempDir;
|
||||||
|
|
||||||
@ -207,12 +221,10 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
session = levelStorageSource.createAccess("faweregentempworld", levelStemResourceKey);
|
session = levelStorageSource.createAccess("faweregentempworld", levelStemResourceKey);
|
||||||
PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData;
|
PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData;
|
||||||
|
|
||||||
BiomeProvider biomeProvider = getBiomeProvider();
|
|
||||||
|
|
||||||
MinecraftServer server = originalServerWorld.getCraftServer().getServer();
|
MinecraftServer server = originalServerWorld.getCraftServer().getServer();
|
||||||
WorldGenSettings originalOpts = originalWorldData.worldGenSettings();
|
WorldOptions originalOpts = originalWorldData.worldGenOptions();
|
||||||
WorldGenSettings newOpts = options.getSeed().isPresent()
|
WorldOptions newOpts = options.getSeed().isPresent()
|
||||||
? originalOpts.withSeed(originalWorldData.isHardcore(), OptionalLong.of(seed))
|
? originalOpts.withSeed(OptionalLong.of(seed))
|
||||||
: originalOpts;
|
: originalOpts;
|
||||||
LevelSettings newWorldSettings = new LevelSettings(
|
LevelSettings newWorldSettings = new LevelSettings(
|
||||||
"faweregentempworld",
|
"faweregentempworld",
|
||||||
@ -221,9 +233,19 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
originalWorldData.settings.difficulty(),
|
originalWorldData.settings.difficulty(),
|
||||||
originalWorldData.settings.allowCommands(),
|
originalWorldData.settings.allowCommands(),
|
||||||
originalWorldData.settings.gameRules(),
|
originalWorldData.settings.gameRules(),
|
||||||
originalWorldData.settings.getDataPackConfig()
|
originalWorldData.settings.getDataConfiguration()
|
||||||
);
|
);
|
||||||
PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, Lifecycle.stable());
|
|
||||||
|
PrimaryLevelData.SpecialWorldProperty specialWorldProperty =
|
||||||
|
originalWorldData.isFlatWorld()
|
||||||
|
? PrimaryLevelData.SpecialWorldProperty.FLAT
|
||||||
|
: originalWorldData.isDebugWorld()
|
||||||
|
? PrimaryLevelData.SpecialWorldProperty.DEBUG
|
||||||
|
: PrimaryLevelData.SpecialWorldProperty.NONE;
|
||||||
|
PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, specialWorldProperty, Lifecycle.stable());
|
||||||
|
|
||||||
|
BiomeProvider biomeProvider = getBiomeProvider();
|
||||||
|
|
||||||
|
|
||||||
//init world
|
//init world
|
||||||
freshWorld = Fawe.instance().getQueueHandler().sync((Supplier<ServerLevel>) () -> new ServerLevel(
|
freshWorld = Fawe.instance().getQueueHandler().sync((Supplier<ServerLevel>) () -> new ServerLevel(
|
||||||
@ -232,66 +254,70 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
session,
|
session,
|
||||||
newWorldData,
|
newWorldData,
|
||||||
originalServerWorld.dimension(),
|
originalServerWorld.dimension(),
|
||||||
originalServerWorld.dimensionTypeRegistration(),
|
DedicatedServer.getServer().registryAccess().registry(Registries.LEVEL_STEM).orElseThrow()
|
||||||
|
.getOrThrow(levelStemResourceKey),
|
||||||
new RegenNoOpWorldLoadListener(),
|
new RegenNoOpWorldLoadListener(),
|
||||||
// placeholder. Required for new ChunkProviderServer, but we create and then set it later
|
|
||||||
newOpts.dimensions().getOrThrow(levelStemResourceKey).generator(),
|
|
||||||
originalServerWorld.isDebug(),
|
originalServerWorld.isDebug(),
|
||||||
seed,
|
seed,
|
||||||
ImmutableList.of(),
|
ImmutableList.of(),
|
||||||
false,
|
false,
|
||||||
|
originalServerWorld.getRandomSequences(),
|
||||||
environment,
|
environment,
|
||||||
generator,
|
generator,
|
||||||
biomeProvider
|
biomeProvider
|
||||||
) {
|
) {
|
||||||
private final Holder<Biome> singleBiome = options.hasBiomeType() ? BuiltinRegistries.BIOME.asHolderIdMap().byId(
|
|
||||||
|
private final Holder<Biome> singleBiome = options.hasBiomeType() ? DedicatedServer.getServer().registryAccess()
|
||||||
|
.registryOrThrow(BIOME).asHolderIdMap().byIdOrThrow(
|
||||||
WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType())
|
WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType())
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick(BooleanSupplier shouldKeepTicking) { //no ticking
|
public void tick(@NotNull BooleanSupplier shouldKeepTicking) { //no ticking
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Holder<Biome> getUncachedNoiseBiome(int biomeX, int biomeY, int biomeZ) {
|
public @NotNull Holder<Biome> getUncachedNoiseBiome(int biomeX, int biomeY, int biomeZ) {
|
||||||
if (options.hasBiomeType()) {
|
if (options.hasBiomeType()) {
|
||||||
return singleBiome;
|
return singleBiome;
|
||||||
}
|
}
|
||||||
return PaperweightRegen.this.chunkGenerator.getBiomeSource().getNoiseBiome(biomeX, biomeY, biomeZ,
|
return PaperweightRegen.this.chunkGenerator.getBiomeSource().getNoiseBiome(
|
||||||
PaperweightRegen.this.chunkGenerator.climateSampler()
|
biomeX, biomeY, biomeZ, getChunkSource().randomState().sampler()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}).get();
|
}).get();
|
||||||
freshWorld.noSave = true;
|
freshWorld.noSave = true;
|
||||||
removeWorldFromWorldsMap();
|
removeWorldFromWorldsMap();
|
||||||
newWorldData.checkName(originalServerWorld.serverLevelData.getLevelName()); //rename to original world name
|
newWorldData.checkName(originalServerWorld.serverLevelData.getLevelName()); //rename to original world name
|
||||||
if (paperConfigField != null) {
|
if (paperConfigField != null) {
|
||||||
paperConfigField.set(freshWorld, originalServerWorld.paperConfig);
|
paperConfigField.set(freshWorld, originalServerWorld.paperConfig());
|
||||||
}
|
}
|
||||||
|
|
||||||
//generator
|
|
||||||
ChunkGenerator originalGenerator = originalChunkProvider.getGenerator();
|
ChunkGenerator originalGenerator = originalChunkProvider.getGenerator();
|
||||||
if (originalGenerator instanceof FlatLevelSource flatLevelSource) {
|
if (originalGenerator instanceof FlatLevelSource flatLevelSource) {
|
||||||
FlatLevelGeneratorSettings generatorSettingFlat = flatLevelSource.settings();
|
FlatLevelGeneratorSettings generatorSettingFlat = flatLevelSource.settings();
|
||||||
chunkGenerator = new FlatLevelSource(originalGenerator.structureSets, generatorSettingFlat);
|
chunkGenerator = new FlatLevelSource(generatorSettingFlat);
|
||||||
} else if (originalGenerator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) {
|
} else if (originalGenerator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) {
|
||||||
Holder<NoiseGeneratorSettings> generatorSettingBaseSupplier =
|
Holder<NoiseGeneratorSettings> generatorSettingBaseSupplier = (Holder<NoiseGeneratorSettings>)
|
||||||
(Holder<NoiseGeneratorSettings>) generatorSettingBaseSupplierField
|
generatorSettingBaseSupplierField.get(noiseBasedChunkGenerator);
|
||||||
.get(originalGenerator);
|
|
||||||
BiomeSource biomeSource;
|
BiomeSource biomeSource;
|
||||||
if (options.hasBiomeType()) {
|
if (options.hasBiomeType()) {
|
||||||
biomeSource = new FixedBiomeSource(BuiltinRegistries.BIOME
|
biomeSource = new FixedBiomeSource(
|
||||||
.asHolderIdMap()
|
DedicatedServer.getServer().registryAccess()
|
||||||
.byId(WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType())));
|
.registryOrThrow(BIOME).asHolderIdMap().byIdOrThrow(
|
||||||
|
WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType())
|
||||||
|
)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
biomeSource = originalGenerator.getBiomeSource();
|
biomeSource = originalGenerator.getBiomeSource();
|
||||||
}
|
}
|
||||||
chunkGenerator = new NoiseBasedChunkGenerator(originalGenerator.structureSets, noiseBasedChunkGenerator.noises,
|
chunkGenerator = new NoiseBasedChunkGenerator(
|
||||||
biomeSource, seed,
|
biomeSource,
|
||||||
generatorSettingBaseSupplier
|
generatorSettingBaseSupplier
|
||||||
);
|
);
|
||||||
} else if (originalGenerator instanceof CustomChunkGenerator customChunkGenerator) {
|
} else if (originalGenerator instanceof CustomChunkGenerator customChunkGenerator) {
|
||||||
chunkGenerator = customChunkGenerator.delegate;
|
chunkGenerator = customChunkGenerator.getDelegate();
|
||||||
} else {
|
} else {
|
||||||
LOGGER.error("Unsupported generator type {}", originalGenerator.getClass().getName());
|
LOGGER.error("Unsupported generator type {}", originalGenerator.getClass().getName());
|
||||||
return false;
|
return false;
|
||||||
@ -300,22 +326,8 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
chunkGenerator = new CustomChunkGenerator(freshWorld, chunkGenerator, generator);
|
chunkGenerator = new CustomChunkGenerator(freshWorld, chunkGenerator, generator);
|
||||||
generateConcurrent = generator.isParallelCapable();
|
generateConcurrent = generator.isParallelCapable();
|
||||||
}
|
}
|
||||||
|
// chunkGenerator.conf = freshWorld.spigotConfig; - Does not exist anymore, may need to be re-addressed
|
||||||
|
|
||||||
if (seed == originalOpts.seed() && !options.hasBiomeType()) {
|
|
||||||
// Optimisation for needless ring position calculation when the seed and biome is the same.
|
|
||||||
boolean hasGeneratedPositions = hasGeneratedPositionsField.getBoolean(originalGenerator);
|
|
||||||
if (hasGeneratedPositions) {
|
|
||||||
Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>> ringPositions =
|
|
||||||
(Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>>) ringPositionsField.get(
|
|
||||||
originalGenerator);
|
|
||||||
Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>> copy = new Object2ObjectArrayMap<>(ringPositions);
|
|
||||||
ringPositionsField.set(chunkGenerator, copy);
|
|
||||||
hasGeneratedPositionsField.setBoolean(chunkGenerator, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
chunkGenerator.conf = originalServerWorld.spigotConfig;
|
|
||||||
freshChunkProvider = new ServerChunkCache(
|
freshChunkProvider = new ServerChunkCache(
|
||||||
freshWorld,
|
freshWorld,
|
||||||
session,
|
session,
|
||||||
@ -333,7 +345,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
) {
|
) {
|
||||||
// redirect to LevelChunks created in #createChunks
|
// redirect to LevelChunks created in #createChunks
|
||||||
@Override
|
@Override
|
||||||
public ChunkAccess getChunk(int x, int z, ChunkStatus chunkstatus, boolean create) {
|
public ChunkAccess getChunk(int x, int z, @NotNull ChunkStatus chunkstatus, boolean create) {
|
||||||
ChunkAccess chunkAccess = getChunkAt(x, z);
|
ChunkAccess chunkAccess = getChunkAt(x, z);
|
||||||
if (chunkAccess == null && create) {
|
if (chunkAccess == null && create) {
|
||||||
chunkAccess = createChunk(getProtoChunkAt(x, z));
|
chunkAccess = createChunk(getProtoChunkAt(x, z));
|
||||||
@ -342,11 +354,32 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (seed == originalOpts.seed() && !options.hasBiomeType()) {
|
||||||
|
// Optimisation for needless ring position calculation when the seed and biome is the same.
|
||||||
|
ChunkGeneratorStructureState state = (ChunkGeneratorStructureState) generatorStructureStateField.get(
|
||||||
|
originalChunkProvider.chunkMap);
|
||||||
|
boolean hasGeneratedPositions = hasGeneratedPositionsField.getBoolean(state);
|
||||||
|
if (hasGeneratedPositions) {
|
||||||
|
Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>> origPositions =
|
||||||
|
(Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>>) ringPositionsField.get(state);
|
||||||
|
Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>> copy = new Object2ObjectArrayMap<>(
|
||||||
|
origPositions);
|
||||||
|
ChunkGeneratorStructureState newState = (ChunkGeneratorStructureState) generatorStructureStateField.get(
|
||||||
|
freshChunkProvider.chunkMap);
|
||||||
|
ringPositionsField.set(newState, copy);
|
||||||
|
hasGeneratedPositionsField.setBoolean(newState, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
chunkSourceField.set(freshWorld, freshChunkProvider);
|
chunkSourceField.set(freshWorld, freshChunkProvider);
|
||||||
//let's start then
|
//let's start then
|
||||||
structureManager = server.getStructureManager();
|
structureTemplateManager = server.getStructureManager();
|
||||||
threadedLevelLightEngine = freshChunkProvider.getLightEngine();
|
threadedLevelLightEngine = new NoOpLightEngine(freshChunkProvider);
|
||||||
|
|
||||||
|
this.worldGenContext = new WorldGenContext(freshWorld, chunkGenerator, structureTemplateManager,
|
||||||
|
threadedLevelLightEngine
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,7 +395,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
Fawe.instance().getQueueHandler().sync(() -> {
|
Fawe.instance().getQueueHandler().sync(() -> {
|
||||||
try {
|
try {
|
||||||
freshChunkProvider.close(false);
|
freshChunkProvider.close(false);
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -385,7 +418,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
@Override
|
@Override
|
||||||
protected ProtoChunk createProtoChunk(int x, int z) {
|
protected ProtoChunk createProtoChunk(int x, int z) {
|
||||||
return new FastProtoChunk(new ChunkPos(x, z), UpgradeData.EMPTY, freshWorld,
|
return new FastProtoChunk(new ChunkPos(x, z), UpgradeData.EMPTY, freshWorld,
|
||||||
this.freshWorld.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), null
|
this.freshWorld.registryAccess().registryOrThrow(BIOME), null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,7 +444,11 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
@Override
|
@Override
|
||||||
protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blockPopulator) {
|
protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blockPopulator) {
|
||||||
// BlockPopulator#populate has to be called synchronously for TileEntity access
|
// BlockPopulator#populate has to be called synchronously for TileEntity access
|
||||||
TaskManager.taskManager().task(() -> blockPopulator.populate(freshWorld.getWorld(), random, levelChunk.getBukkitChunk()));
|
TaskManager.taskManager().task(() -> {
|
||||||
|
final CraftWorld world = freshWorld.getWorld();
|
||||||
|
final Chunk chunk = world.getChunkAt(levelChunk.locX, levelChunk.locZ);
|
||||||
|
blockPopulator.populate(world, random, chunk);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -427,14 +464,12 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
//util
|
//util
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void removeWorldFromWorldsMap() {
|
private void removeWorldFromWorldsMap() {
|
||||||
Fawe.instance().getQueueHandler().sync(() -> {
|
|
||||||
try {
|
try {
|
||||||
Map<String, org.bukkit.World> map = (Map<String, org.bukkit.World>) serverWorldsField.get(Bukkit.getServer());
|
Map<String, org.bukkit.World> map = (Map<String, org.bukkit.World>) serverWorldsField.get(Bukkit.getServer());
|
||||||
map.remove("faweregentempworld");
|
map.remove("faweregentempworld");
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResourceKey<LevelStem> getWorldDimKey(org.bukkit.World.Environment env) {
|
private ResourceKey<LevelStem> getWorldDimKey(org.bukkit.World.Environment env) {
|
||||||
@ -451,11 +486,15 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateSpawnPos(ChunkPos spawnPos) {
|
public void updateSpawnPos(@NotNull ChunkPos spawnPos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStatusChange(ChunkPos pos, @Nullable ChunkStatus status) {
|
public void onStatusChange(
|
||||||
|
final @NotNull ChunkPos pos,
|
||||||
|
@org.jetbrains.annotations.Nullable final net.minecraft.world.level.chunk.status.ChunkStatus status
|
||||||
|
) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -487,15 +526,14 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
|
|
||||||
// avoid warning on paper
|
// avoid warning on paper
|
||||||
|
|
||||||
// compatibility with spigot
|
@SuppressWarnings("unused") // compatibility with spigot
|
||||||
|
|
||||||
public boolean generateFlatBedrock() {
|
public boolean generateFlatBedrock() {
|
||||||
return generateFlatBedrock;
|
return generateFlatBedrock;
|
||||||
}
|
}
|
||||||
|
|
||||||
// no one will ever see the entities!
|
// no one will ever see the entities!
|
||||||
@Override
|
@Override
|
||||||
public List<CompoundTag> getEntities() {
|
public @NotNull List<CompoundTag> getEntities() {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,23 +554,41 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String name() {
|
public String name() {
|
||||||
return chunkStatus.getName();
|
return chunkStatus.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<?> processChunk(List<ChunkAccess> accessibleChunks) {
|
public CompletableFuture<?> processChunk(List<ChunkAccess> accessibleChunks) {
|
||||||
return chunkStatus.generate(
|
return chunkStatus.generate(
|
||||||
Runnable::run, // TODO revisit, we might profit from this somehow?
|
worldGenContext,
|
||||||
freshWorld,
|
Runnable::run,
|
||||||
chunkGenerator,
|
CompletableFuture::completedFuture,
|
||||||
structureManager,
|
accessibleChunks
|
||||||
threadedLevelLightEngine,
|
|
||||||
c -> CompletableFuture.completedFuture(Either.left(c)),
|
|
||||||
accessibleChunks,
|
|
||||||
true
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A light engine that does nothing. As light is calculated after pasting anyway, we can avoid
|
||||||
|
* work this way.
|
||||||
|
*/
|
||||||
|
static class NoOpLightEngine extends ThreadedLevelLightEngine {
|
||||||
|
|
||||||
|
private static final ProcessorMailbox<Runnable> MAILBOX = ProcessorMailbox.create(task -> {
|
||||||
|
}, "fawe-no-op");
|
||||||
|
private static final ProcessorHandle<Message<Runnable>> HANDLE = ProcessorHandle.of("fawe-no-op", m -> {
|
||||||
|
});
|
||||||
|
|
||||||
|
public NoOpLightEngine(final ServerChunkCache chunkProvider) {
|
||||||
|
super(chunkProvider, chunkProvider.chunkMap, false, MAILBOX, HANDLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull CompletableFuture<ChunkAccess> lightChunk(final @NotNull ChunkAccess chunk, final boolean excludeBlocks) {
|
||||||
|
return CompletableFuture.completedFuture(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -40,6 +40,7 @@ repositories {
|
|||||||
name = "Glaremasters"
|
name = "Glaremasters"
|
||||||
url = uri("https://repo.glaremasters.me/repository/towny/")
|
url = uri("https://repo.glaremasters.me/repository/towny/")
|
||||||
}
|
}
|
||||||
|
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") // TODO Remove when 4.17.0 is released
|
||||||
flatDir { dir(File("src/main/resources")) }
|
flatDir { dir(File("src/main/resources")) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,7 +183,7 @@ tasks.named<ShadowJar>("shadowJar") {
|
|||||||
include(dependency("org.lz4:lz4-java:1.8.0"))
|
include(dependency("org.lz4:lz4-java:1.8.0"))
|
||||||
}
|
}
|
||||||
relocate("net.kyori", "com.fastasyncworldedit.core.adventure") {
|
relocate("net.kyori", "com.fastasyncworldedit.core.adventure") {
|
||||||
include(dependency("net.kyori:adventure-nbt:4.16.0"))
|
include(dependency("net.kyori:adventure-nbt:4.17.0"))
|
||||||
}
|
}
|
||||||
relocate("com.zaxxer", "com.fastasyncworldedit.core.math") {
|
relocate("com.zaxxer", "com.fastasyncworldedit.core.math") {
|
||||||
include(dependency("com.zaxxer:SparseBitSet:1.3"))
|
include(dependency("com.zaxxer:SparseBitSet:1.3"))
|
||||||
@ -214,7 +215,7 @@ tasks {
|
|||||||
versionNumber.set("${project.version}")
|
versionNumber.set("${project.version}")
|
||||||
versionType.set("release")
|
versionType.set("release")
|
||||||
uploadFile.set(file("build/libs/${rootProject.name}-Bukkit-${project.version}.jar"))
|
uploadFile.set(file("build/libs/${rootProject.name}-Bukkit-${project.version}.jar"))
|
||||||
gameVersions.addAll(listOf("1.20.4", "1.20.3", "1.20.2", "1.20.1", "1.20", "1.19.4", "1.18.2"))
|
gameVersions.addAll(listOf("1.20.6", "1.20.5", "1.20.3", "1.20.2", "1.20.1", "1.20", "1.19.4"))
|
||||||
loaders.addAll(listOf("paper", "spigot"))
|
loaders.addAll(listOf("paper", "spigot"))
|
||||||
changelog.set("The changelog is available on GitHub: https://github.com/IntellectualSites/" +
|
changelog.set("The changelog is available on GitHub: https://github.com/IntellectualSites/" +
|
||||||
"FastAsyncWorldEdit/releases/tag/${project.version}")
|
"FastAsyncWorldEdit/releases/tag/${project.version}")
|
||||||
|
@ -5,6 +5,7 @@ import com.fastasyncworldedit.core.queue.IChunkCache;
|
|||||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||||
import com.fastasyncworldedit.core.queue.implementation.SingleThreadQueueExtent;
|
import com.fastasyncworldedit.core.queue.implementation.SingleThreadQueueExtent;
|
||||||
import com.fastasyncworldedit.core.util.MathMan;
|
import com.fastasyncworldedit.core.util.MathMan;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
@ -24,11 +25,16 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
|
|||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||||
import it.unimi.dsi.fastutil.longs.LongList;
|
import it.unimi.dsi.fastutil.longs.LongList;
|
||||||
|
import jdk.jfr.Category;
|
||||||
|
import jdk.jfr.Event;
|
||||||
|
import jdk.jfr.Label;
|
||||||
|
import jdk.jfr.Name;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.bukkit.generator.BiomeProvider;
|
import org.bukkit.generator.BiomeProvider;
|
||||||
import org.bukkit.generator.BlockPopulator;
|
import org.bukkit.generator.BlockPopulator;
|
||||||
import org.bukkit.generator.WorldInfo;
|
import org.bukkit.generator.WorldInfo;
|
||||||
|
|
||||||
|
import java.util.AbstractList;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@ -36,6 +42,7 @@ import java.util.Iterator;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
@ -62,7 +69,7 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
|||||||
protected final RegenOptions options;
|
protected final RegenOptions options;
|
||||||
|
|
||||||
//runtime
|
//runtime
|
||||||
protected final Map<ChunkStatus, Concurrency> chunkStatuses = new LinkedHashMap<>();
|
protected final LinkedHashMap<ChunkStatus, Concurrency> chunkStatuses = new LinkedHashMap<>(); // TODO (j21): use SequencedMap
|
||||||
private final Long2ObjectLinkedOpenHashMap<ProtoChunk> protoChunks = new Long2ObjectLinkedOpenHashMap<>();
|
private final Long2ObjectLinkedOpenHashMap<ProtoChunk> protoChunks = new Long2ObjectLinkedOpenHashMap<>();
|
||||||
private final Long2ObjectOpenHashMap<Chunk> chunks = new Long2ObjectOpenHashMap<>();
|
private final Long2ObjectOpenHashMap<Chunk> chunks = new Long2ObjectOpenHashMap<>();
|
||||||
protected boolean generateConcurrent = true;
|
protected boolean generateConcurrent = true;
|
||||||
@ -172,51 +179,70 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
|||||||
//TODO: can we get that required radius down without affecting chunk generation (e.g. strucures, features, ...)?
|
//TODO: can we get that required radius down without affecting chunk generation (e.g. strucures, features, ...)?
|
||||||
//for now it is working well and fast, if we are bored in the future we could do the research (a lot of it) to reduce the border radius
|
//for now it is working well and fast, if we are bored in the future we could do the research (a lot of it) to reduce the border radius
|
||||||
|
|
||||||
//generate chunk coords lists with a certain radius
|
// to get the chunks we need to generate in the nth chunk status, we need to know how many chunks
|
||||||
Int2ObjectOpenHashMap<long[]> chunkCoordsForRadius = new Int2ObjectOpenHashMap<>();
|
// we need to generate in the n + 1 th chunk status. Summing up the margin solves that
|
||||||
chunkStatuses.keySet().stream().mapToInt(ChunkStatusWrapper::requiredNeighborChunkRadius0).distinct().forEach(radius -> {
|
LinkedHashMap<ChunkStatus, long[]> chunkCoordsForChunkStatus = new LinkedHashMap<>();
|
||||||
if (radius == -1) { //ignore ChunkStatus.EMPTY
|
int borderSum = 1;
|
||||||
return;
|
// TODO (j21): use SequencedMap#sequencedKeySet().reversed()
|
||||||
|
final List<ChunkStatus> reversedKeys = Lists.reverse(new ArrayList<>(chunkStatuses.keySet()));
|
||||||
|
for (final ChunkStatus status : reversedKeys) {
|
||||||
|
chunkCoordsForChunkStatus.put(status, getChunkCoordsRegen(region, borderSum));
|
||||||
|
borderSum += status.requiredNeighborChunkRadius();
|
||||||
}
|
}
|
||||||
int border = 10 - radius; //9 = 8 + 1, 8: max border radius used in chunk stages, 1: need 1 extra chunk for chunk
|
|
||||||
// features to generate at the border of the region
|
|
||||||
chunkCoordsForRadius.put(radius, getChunkCoordsRegen(region, border));
|
|
||||||
});
|
|
||||||
|
|
||||||
//create chunks
|
//create chunks
|
||||||
for (long xz : chunkCoordsForRadius.get(0)) {
|
// TODO (j21): use SequencedMap#firstEntry().getKey()
|
||||||
|
for (long xz : chunkCoordsForChunkStatus.get(chunkStatuses.keySet().iterator().next())) {
|
||||||
ProtoChunk chunk = createProtoChunk(MathMan.unpairIntX(xz), MathMan.unpairIntY(xz));
|
ProtoChunk chunk = createProtoChunk(MathMan.unpairIntX(xz), MathMan.unpairIntY(xz));
|
||||||
protoChunks.put(xz, chunk);
|
protoChunks.put(xz, chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
//generate lists for RegionLimitedWorldAccess, need to be square with odd length (e.g. 17x17), 17 = 1 middle chunk + 8 border chunks * 2
|
// a memory-efficient, lightweight "list" that calculates index -> ChunkAccess
|
||||||
Int2ObjectOpenHashMap<Long2ObjectOpenHashMap<List<IChunkAccess>>> worldLimits = new Int2ObjectOpenHashMap<>();
|
// as needed when accessed
|
||||||
chunkStatuses.keySet().stream().mapToInt(ChunkStatusWrapper::requiredNeighborChunkRadius0).distinct().forEach(radius -> {
|
class LazyChunkList extends AbstractList<IChunkAccess> {
|
||||||
if (radius == -1) { //ignore ChunkStatus.EMPTY
|
private final int size;
|
||||||
return;
|
private final int minX;
|
||||||
|
private final int minZ;
|
||||||
|
private final int sizeSqrt;
|
||||||
|
|
||||||
|
LazyChunkList(int radius, int centerX, int centerZ) {
|
||||||
|
this.sizeSqrt = radius + 1 + radius; // length of one side
|
||||||
|
this.size = this.sizeSqrt * this.sizeSqrt;
|
||||||
|
this.minX = centerX - radius;
|
||||||
|
this.minZ = centerZ - radius;
|
||||||
}
|
}
|
||||||
Long2ObjectOpenHashMap<List<IChunkAccess>> map = new Long2ObjectOpenHashMap<>();
|
@Override
|
||||||
for (long xz : chunkCoordsForRadius.get(radius)) {
|
public IChunkAccess get(final int index) {
|
||||||
int x = MathMan.unpairIntX(xz);
|
Objects.checkIndex(index, size);
|
||||||
int z = MathMan.unpairIntY(xz);
|
int absX = (index % sizeSqrt) + minX;
|
||||||
List<IChunkAccess> l = new ArrayList<>((radius + 1 + radius) * (radius + 1 + radius));
|
int absZ = (index / sizeSqrt) + minZ;
|
||||||
for (int zz = z - radius; zz <= z + radius; zz++) { //order is important, first z then x
|
return protoChunks.get(MathMan.pairInt(absX, absZ));
|
||||||
for (int xx = x - radius; xx <= x + radius; xx++) {
|
|
||||||
l.add(protoChunks.get(MathMan.pairInt(xx, zz)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
map.put(xz, l);
|
|
||||||
|
}
|
||||||
|
@Label("Regeneration")
|
||||||
|
@Category("FAWE")
|
||||||
|
@Name("fawe.regen")
|
||||||
|
class RegenerationEvent extends Event {
|
||||||
|
private String chunkStatus;
|
||||||
|
private int chunksToProcess;
|
||||||
}
|
}
|
||||||
worldLimits.put(radius, map);
|
|
||||||
});
|
|
||||||
|
|
||||||
//run generation tasks excluding FULL chunk status
|
//run generation tasks excluding FULL chunk status
|
||||||
for (Map.Entry<ChunkStatus, Concurrency> entry : chunkStatuses.entrySet()) {
|
for (Map.Entry<ChunkStatus, Concurrency> entry : chunkStatuses.entrySet()) {
|
||||||
ChunkStatus chunkStatus = entry.getKey();
|
ChunkStatus chunkStatus = entry.getKey();
|
||||||
int radius = chunkStatus.requiredNeighborChunkRadius0();
|
final RegenerationEvent event = new RegenerationEvent();
|
||||||
|
event.begin();
|
||||||
|
event.chunkStatus = chunkStatus.name();
|
||||||
|
int radius = Math.max(1, chunkStatus.requiredNeighborChunkRadius0());
|
||||||
|
|
||||||
long[] coords = chunkCoordsForRadius.get(radius);
|
long[] coords = chunkCoordsForChunkStatus.get(chunkStatus);
|
||||||
Long2ObjectOpenHashMap<List<IChunkAccess>> limitsForRadius = worldLimits.get(radius);
|
event.chunksToProcess = coords.length;
|
||||||
if (this.generateConcurrent && entry.getValue() == Concurrency.RADIUS) {
|
if (this.generateConcurrent && entry.getValue() == Concurrency.RADIUS) {
|
||||||
SequentialTasks<ConcurrentTasks<LongList>> tasks = getChunkStatusTaskRows(coords, radius);
|
SequentialTasks<ConcurrentTasks<LongList>> tasks = getChunkStatusTaskRows(coords, radius);
|
||||||
for (ConcurrentTasks<LongList> para : tasks) {
|
for (ConcurrentTasks<LongList> para : tasks) {
|
||||||
@ -224,7 +250,8 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
|||||||
for (LongList row : para) {
|
for (LongList row : para) {
|
||||||
scheduled.add(() -> {
|
scheduled.add(() -> {
|
||||||
for (long xz : row) {
|
for (long xz : row) {
|
||||||
chunkStatus.processChunkSave(xz, limitsForRadius.get(xz));
|
chunkStatus.processChunkSave(xz, new LazyChunkList(radius, MathMan.unpairIntX(xz),
|
||||||
|
MathMan.unpairIntY(xz)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -234,7 +261,8 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
|||||||
// every chunk can be processed individually
|
// every chunk can be processed individually
|
||||||
List<Runnable> scheduled = new ArrayList<>(coords.length);
|
List<Runnable> scheduled = new ArrayList<>(coords.length);
|
||||||
for (long xz : coords) {
|
for (long xz : coords) {
|
||||||
scheduled.add(() -> chunkStatus.processChunkSave(xz, limitsForRadius.get(xz)));
|
scheduled.add(() -> chunkStatus.processChunkSave(xz, new LazyChunkList(radius, MathMan.unpairIntX(xz),
|
||||||
|
MathMan.unpairIntY(xz))));
|
||||||
}
|
}
|
||||||
runAndWait(scheduled);
|
runAndWait(scheduled);
|
||||||
} else { // Concurrency.NONE or generateConcurrent == false
|
} else { // Concurrency.NONE or generateConcurrent == false
|
||||||
@ -242,28 +270,33 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
|||||||
// running regen on the main thread otherwise triggers async-only events on the main thread
|
// running regen on the main thread otherwise triggers async-only events on the main thread
|
||||||
executor.submit(() -> {
|
executor.submit(() -> {
|
||||||
for (long xz : coords) {
|
for (long xz : coords) {
|
||||||
chunkStatus.processChunkSave(xz, limitsForRadius.get(xz));
|
chunkStatus.processChunkSave(xz, new LazyChunkList(radius, MathMan.unpairIntX(xz),
|
||||||
|
MathMan.unpairIntY(xz)));
|
||||||
}
|
}
|
||||||
}).get(); // wait until finished this step
|
}).get(); // wait until finished this step
|
||||||
}
|
}
|
||||||
|
event.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
//convert to proper chunks
|
//convert to proper chunks
|
||||||
for (long xz : chunkCoordsForRadius.get(0)) {
|
// TODO (j21): use SequencedMap#firstEntry().getValue()
|
||||||
|
for (long xz : chunkCoordsForChunkStatus.values().iterator().next()) {
|
||||||
ProtoChunk proto = protoChunks.get(xz);
|
ProtoChunk proto = protoChunks.get(xz);
|
||||||
chunks.put(xz, createChunk(proto));
|
chunks.put(xz, createChunk(proto));
|
||||||
}
|
}
|
||||||
|
|
||||||
//final chunkstatus
|
//final chunkstatus
|
||||||
ChunkStatus FULL = getFullChunkStatus();
|
ChunkStatus FULL = getFullChunkStatus();
|
||||||
for (long xz : chunkCoordsForRadius.get(0)) { //FULL.requiredNeighbourChunkRadius() == 0!
|
// TODO (j21): use SequencedMap#firstEntry().getValue()
|
||||||
|
for (long xz : chunkCoordsForChunkStatus.values().iterator().next()) { //FULL.requiredNeighbourChunkRadius() == 0!
|
||||||
Chunk chunk = chunks.get(xz);
|
Chunk chunk = chunks.get(xz);
|
||||||
FULL.processChunkSave(xz, List.of(chunk));
|
FULL.processChunkSave(xz, List.of(chunk));
|
||||||
}
|
}
|
||||||
|
|
||||||
//populate
|
//populate
|
||||||
List<BlockPopulator> populators = getBlockPopulators();
|
List<BlockPopulator> populators = getBlockPopulators();
|
||||||
for (long xz : chunkCoordsForRadius.get(0)) {
|
// TODO (j21): use SequencedMap#firstEntry().getValue()
|
||||||
|
for (long xz : chunkCoordsForChunkStatus.values().iterator().next()) {
|
||||||
int x = MathMan.unpairIntX(xz);
|
int x = MathMan.unpairIntX(xz);
|
||||||
int z = MathMan.unpairIntY(xz);
|
int z = MathMan.unpairIntY(xz);
|
||||||
|
|
||||||
@ -277,8 +310,10 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
source = new SingleThreadQueueExtent(BukkitWorld.HAS_MIN_Y ? originalBukkitWorld.getMinHeight() : 0,
|
source = new SingleThreadQueueExtent(
|
||||||
BukkitWorld.HAS_MIN_Y ? originalBukkitWorld.getMaxHeight() : 256);
|
BukkitWorld.HAS_MIN_Y ? originalBukkitWorld.getMinHeight() : 0,
|
||||||
|
BukkitWorld.HAS_MIN_Y ? originalBukkitWorld.getMaxHeight() : 256
|
||||||
|
);
|
||||||
source.init(target, initSourceQueueCache(), null);
|
source.init(target, initSourceQueueCache(), null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -503,7 +538,7 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
|||||||
int numlists = Math.min(requiredNeighbors * 2 + 1, maxZ - minZ + 1);
|
int numlists = Math.min(requiredNeighbors * 2 + 1, maxZ - minZ + 1);
|
||||||
|
|
||||||
Int2ObjectOpenHashMap<LongList> byZ = new Int2ObjectOpenHashMap<>();
|
Int2ObjectOpenHashMap<LongList> byZ = new Int2ObjectOpenHashMap<>();
|
||||||
int expectedListLength = (coordsCount + 1) / (maxZ - minZ);
|
int expectedListLength = (coordsCount + 1) / (maxZ - minZ + 2);
|
||||||
|
|
||||||
//init lists
|
//init lists
|
||||||
for (int i = minZ; i <= maxZ; i++) {
|
for (int i = minZ; i <= maxZ; i++) {
|
||||||
@ -581,13 +616,16 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
|||||||
try {
|
try {
|
||||||
processChunk(accessibleChunks).get();
|
processChunk(accessibleChunks).get();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.error(
|
LOGGER.error("Error while running {} on chunk {}/{}",
|
||||||
"Error while running " + name() + " on chunk " + MathMan.unpairIntX(xz) + "/" + MathMan.unpairIntY(xz),
|
name(), MathMan.unpairIntX(xz), MathMan.unpairIntY(xz), e);
|
||||||
e
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SequentialTasks<T> extends Tasks<T> {
|
public static class SequentialTasks<T> extends Tasks<T> {
|
||||||
|
@ -135,7 +135,7 @@ public abstract class ChunkListener implements Listener {
|
|||||||
@Deprecated(since = "2.0.0")
|
@Deprecated(since = "2.0.0")
|
||||||
public void cleanup(Chunk chunk) {
|
public void cleanup(Chunk chunk) {
|
||||||
for (Entity entity : chunk.getEntities()) {
|
for (Entity entity : chunk.getEntities()) {
|
||||||
if (entity.getType() == EntityType.DROPPED_ITEM) {
|
if (entity.getType() == EntityType.ITEM) {
|
||||||
entity.remove();
|
entity.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
package com.sk89q.bukkit.util;
|
package com.sk89q.bukkit.util;
|
||||||
|
|
||||||
import com.sk89q.util.ReflectionUtil;
|
import com.sk89q.util.ReflectionUtil;
|
||||||
|
import io.papermc.lib.PaperLib;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
@ -96,12 +97,11 @@ public class CommandRegistration {
|
|||||||
return fallbackCommands;
|
return fallbackCommands;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandMap commandMap = ReflectionUtil.getField(plugin.getServer().getPluginManager(), "commandMap");
|
CommandMap commandMap = PaperLib.isPaper() ? Bukkit.getCommandMap() : ReflectionUtil.getField(plugin.getServer().getPluginManager(), "commandMap");
|
||||||
if (commandMap == null) {
|
if (commandMap == null) {
|
||||||
Bukkit.getServer().getLogger().severe(plugin.getDescription().getName()
|
Bukkit.getServer().getLogger().severe(plugin.getDescription().getName()
|
||||||
+ ": Could not retrieve server CommandMap, using fallback instead!");
|
+ ": Could not retrieve server CommandMap");
|
||||||
fallbackCommands = commandMap = new SimpleCommandMap(Bukkit.getServer());
|
throw new IllegalStateException("Failed to retrieve command map, make sure you are running supported server software");
|
||||||
Bukkit.getServer().getPluginManager().registerEvents(new FallbackRegistrationListener(fallbackCommands), plugin);
|
|
||||||
} else {
|
} else {
|
||||||
serverCommandMap = commandMap;
|
serverCommandMap = commandMap;
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "1.8.20"
|
kotlin("jvm") version "1.9.23"
|
||||||
application
|
application
|
||||||
}
|
}
|
||||||
|
|
||||||
applyCommonConfiguration()
|
applyCommonConfiguration()
|
||||||
|
|
||||||
tasks.withType<KotlinCompile> {
|
|
||||||
kotlinOptions.jvmTarget = "17"
|
|
||||||
}
|
|
||||||
|
|
||||||
application.mainClass.set("com.sk89q.worldedit.internal.util.DocumentationPrinter")
|
application.mainClass.set("com.sk89q.worldedit.internal.util.DocumentationPrinter")
|
||||||
tasks.named<JavaExec>("run") {
|
tasks.named<JavaExec>("run") {
|
||||||
workingDir = rootProject.projectDir
|
workingDir = rootProject.projectDir
|
||||||
|
@ -2,6 +2,7 @@ package com.fastasyncworldedit.core.configuration;
|
|||||||
|
|
||||||
import com.fastasyncworldedit.core.configuration.file.YamlConfiguration;
|
import com.fastasyncworldedit.core.configuration.file.YamlConfiguration;
|
||||||
import com.fastasyncworldedit.core.util.StringMan;
|
import com.fastasyncworldedit.core.util.StringMan;
|
||||||
|
import com.sk89q.util.StringUtil;
|
||||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
@ -14,8 +15,10 @@ import java.lang.annotation.RetentionPolicy;
|
|||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -27,6 +30,9 @@ public class Config {
|
|||||||
|
|
||||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||||
|
|
||||||
|
private final Map<String, Object> removedKeyVals = new HashMap<>();
|
||||||
|
private List<String> existingMigrateNodes = null;
|
||||||
|
|
||||||
public Config() {
|
public Config() {
|
||||||
save(new PrintWriter(new ByteArrayOutputStream(0)), getClass(), this, 0);
|
save(new PrintWriter(new ByteArrayOutputStream(0)), getClass(), this, 0);
|
||||||
}
|
}
|
||||||
@ -43,7 +49,8 @@ public class Config {
|
|||||||
try {
|
try {
|
||||||
return (T) field.get(instance);
|
return (T) field.get(instance);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
e.printStackTrace();
|
LOGGER.error("Failed to get config option: {}", key, e);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,6 +74,10 @@ public class Config {
|
|||||||
if (field.getAnnotation(Final.class) != null) {
|
if (field.getAnnotation(Final.class) != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Migrate migrate = field.getAnnotation(Migrate.class);
|
||||||
|
if (existingMigrateNodes != null && migrate != null) {
|
||||||
|
existingMigrateNodes.add(migrate.value());
|
||||||
|
}
|
||||||
if (field.getType() == String.class && !(value instanceof String)) {
|
if (field.getType() == String.class && !(value instanceof String)) {
|
||||||
value = value + "";
|
value = value + "";
|
||||||
}
|
}
|
||||||
@ -74,17 +85,22 @@ public class Config {
|
|||||||
field.set(instance, value);
|
field.set(instance, value);
|
||||||
return;
|
return;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
LOGGER.error("Failed to set config option: {}", key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOGGER.error("Failed to set config option: {}: {} | {} | {}.yml", key, value, instance, root.getSimpleName());
|
removedKeyVals.put(key, value);
|
||||||
|
LOGGER.error(
|
||||||
|
"Failed to set config option: {}: {} | {} | {}.yml. This is likely because it was removed.",
|
||||||
|
key,
|
||||||
|
value,
|
||||||
|
instance,
|
||||||
|
root.getSimpleName()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean load(File file) {
|
public boolean load(File file) {
|
||||||
if (!file.exists()) {
|
existingMigrateNodes = new ArrayList<>();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
YamlConfiguration yml = YamlConfiguration.loadConfiguration(file);
|
YamlConfiguration yml = YamlConfiguration.loadConfiguration(file);
|
||||||
for (String key : yml.getKeys(true)) {
|
for (String key : yml.getKeys(true)) {
|
||||||
Object value = yml.get(key);
|
Object value = yml.get(key);
|
||||||
@ -93,6 +109,10 @@ public class Config {
|
|||||||
}
|
}
|
||||||
set(key, value, getClass());
|
set(key, value, getClass());
|
||||||
}
|
}
|
||||||
|
for (String node : existingMigrateNodes) {
|
||||||
|
removedKeyVals.remove(node);
|
||||||
|
}
|
||||||
|
existingMigrateNodes = null;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +133,7 @@ public class Config {
|
|||||||
save(writer, getClass(), instance, 0);
|
save(writer, getClass(), instance, 0);
|
||||||
writer.close();
|
writer.close();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
LOGGER.error("Failed to save config file: {}", file, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,6 +186,19 @@ public class Config {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that a field should be instantiated / created.
|
||||||
|
*
|
||||||
|
* @since 2.10.0
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target({ElementType.FIELD})
|
||||||
|
public @interface Migrate {
|
||||||
|
|
||||||
|
String value();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Ignore // This is not part of the config
|
@Ignore // This is not part of the config
|
||||||
public static class ConfigBlock<T> {
|
public static class ConfigBlock<T> {
|
||||||
|
|
||||||
@ -222,7 +255,6 @@ public class Config {
|
|||||||
try {
|
try {
|
||||||
String CTRF = System.lineSeparator();
|
String CTRF = System.lineSeparator();
|
||||||
String spacing = StringMan.repeat(" ", indent);
|
String spacing = StringMan.repeat(" ", indent);
|
||||||
HashMap<Class<?>, Object> instances = new HashMap<>();
|
|
||||||
for (Field field : clazz.getFields()) {
|
for (Field field : clazz.getFields()) {
|
||||||
if (field.getAnnotation(Ignore.class) != null) {
|
if (field.getAnnotation(Ignore.class) != null) {
|
||||||
continue;
|
continue;
|
||||||
@ -239,31 +271,14 @@ public class Config {
|
|||||||
}
|
}
|
||||||
if (current == ConfigBlock.class) {
|
if (current == ConfigBlock.class) {
|
||||||
current = (Class<?>) ((ParameterizedType) (field.getGenericType())).getActualTypeArguments()[0];
|
current = (Class<?>) ((ParameterizedType) (field.getGenericType())).getActualTypeArguments()[0];
|
||||||
comment = current.getAnnotation(Comment.class);
|
handleConfigBlockSave(writer, instance, indent, field, spacing, CTRF, current);
|
||||||
if (comment != null) {
|
|
||||||
for (String commentLine : comment.value()) {
|
|
||||||
writer.write(spacing + "# " + commentLine + CTRF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BlockName blockNames = current.getAnnotation(BlockName.class);
|
|
||||||
if (blockNames != null) {
|
|
||||||
writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF);
|
|
||||||
ConfigBlock configBlock = (ConfigBlock) field.get(instance);
|
|
||||||
if (configBlock == null || configBlock.getInstances().isEmpty()) {
|
|
||||||
configBlock = new ConfigBlock();
|
|
||||||
field.set(instance, configBlock);
|
|
||||||
for (String blockName : blockNames.value()) {
|
|
||||||
configBlock.put(blockName, current.getDeclaredConstructor().newInstance());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Save each instance
|
|
||||||
for (Map.Entry<String, Object> entry : ((Map<String, Object>) configBlock.getRaw()).entrySet()) {
|
|
||||||
String key = entry.getKey();
|
|
||||||
writer.write(spacing + " " + toNodeName(key) + ":" + CTRF);
|
|
||||||
save(writer, current, entry.getValue(), indent + 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
|
} else if (!removedKeyVals.isEmpty()) {
|
||||||
|
Migrate migrate = field.getAnnotation(Migrate.class);
|
||||||
|
Object value;
|
||||||
|
if (migrate != null && (value = removedKeyVals.remove(migrate.value())) != null) {
|
||||||
|
field.set(instance, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Create create = field.getAnnotation(Create.class);
|
Create create = field.getAnnotation(Create.class);
|
||||||
if (create != null) {
|
if (create != null) {
|
||||||
@ -281,7 +296,6 @@ public class Config {
|
|||||||
writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF);
|
writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
field.set(instance, value = current.getDeclaredConstructor().newInstance());
|
field.set(instance, value = current.getDeclaredConstructor().newInstance());
|
||||||
instances.put(current, value);
|
|
||||||
}
|
}
|
||||||
save(writer, current, value, indent + 2);
|
save(writer, current, value, indent + 2);
|
||||||
} else {
|
} else {
|
||||||
@ -292,7 +306,42 @@ public class Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
LOGGER.error("Failed to save config file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> void handleConfigBlockSave(
|
||||||
|
PrintWriter writer,
|
||||||
|
Object instance,
|
||||||
|
int indent,
|
||||||
|
Field field,
|
||||||
|
String spacing,
|
||||||
|
String CTRF,
|
||||||
|
Class<T> current
|
||||||
|
) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
|
||||||
|
Comment comment = current.getAnnotation(Comment.class);
|
||||||
|
if (comment != null) {
|
||||||
|
for (String commentLine : comment.value()) {
|
||||||
|
writer.write(spacing + "# " + commentLine + CTRF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BlockName blockNames = current.getAnnotation(BlockName.class);
|
||||||
|
if (blockNames != null) {
|
||||||
|
writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF);
|
||||||
|
ConfigBlock<T> configBlock = (ConfigBlock<T>) field.get(instance);
|
||||||
|
if (configBlock == null || configBlock.getInstances().isEmpty()) {
|
||||||
|
configBlock = new ConfigBlock<>();
|
||||||
|
field.set(instance, configBlock);
|
||||||
|
for (String blockName : blockNames.value()) {
|
||||||
|
configBlock.put(blockName, current.getDeclaredConstructor().newInstance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Save each instance
|
||||||
|
for (Map.Entry<String, T> entry : configBlock.getRaw().entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
writer.write(spacing + " " + toNodeName(key) + ":" + CTRF);
|
||||||
|
save(writer, current, entry.getValue(), indent + 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +360,7 @@ public class Config {
|
|||||||
return field;
|
return field;
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
LOGGER.warn(
|
LOGGER.warn(
|
||||||
"Invalid config field: {} for {}",
|
"Invalid config field: {} for {}. It is possible this is because it has been removed.",
|
||||||
StringMan.join(split, "."),
|
StringMan.join(split, "."),
|
||||||
toNodeName(instance.getClass().getSimpleName())
|
toNodeName(instance.getClass().getSimpleName())
|
||||||
);
|
);
|
||||||
@ -379,7 +428,7 @@ public class Config {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
LOGGER.error("Failed retrieving instance for config node: {}", StringUtil.joinString(split, "."), e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,8 @@ public class Settings extends Config {
|
|||||||
@Create
|
@Create
|
||||||
public REGION_RESTRICTIONS_OPTIONS REGION_RESTRICTIONS_OPTIONS;
|
public REGION_RESTRICTIONS_OPTIONS REGION_RESTRICTIONS_OPTIONS;
|
||||||
@Create
|
@Create
|
||||||
|
public GENERAL GENERAL;
|
||||||
|
@Create
|
||||||
public ConfigBlock<LIMITS> LIMITS;
|
public ConfigBlock<LIMITS> LIMITS;
|
||||||
|
|
||||||
private Settings() {
|
private Settings() {
|
||||||
@ -145,6 +147,14 @@ public class Settings extends Config {
|
|||||||
limit.MAX_HISTORY,
|
limit.MAX_HISTORY,
|
||||||
newLimit.MAX_HISTORY_MB != -1 ? newLimit.MAX_HISTORY_MB : Integer.MAX_VALUE
|
newLimit.MAX_HISTORY_MB != -1 ? newLimit.MAX_HISTORY_MB : Integer.MAX_VALUE
|
||||||
);
|
);
|
||||||
|
limit.SCHEM_FILE_NUM_LIMIT = Math.max(
|
||||||
|
limit.SCHEM_FILE_NUM_LIMIT,
|
||||||
|
newLimit.SCHEM_FILE_NUM_LIMIT != -1 ? newLimit.SCHEM_FILE_NUM_LIMIT : Integer.MAX_VALUE
|
||||||
|
);
|
||||||
|
limit.SCHEM_FILE_SIZE_LIMIT = Math.max(
|
||||||
|
limit.SCHEM_FILE_SIZE_LIMIT,
|
||||||
|
newLimit.SCHEM_FILE_SIZE_LIMIT != -1 ? newLimit.SCHEM_FILE_SIZE_LIMIT : Integer.MAX_VALUE
|
||||||
|
);
|
||||||
limit.MAX_EXPRESSION_MS = Math.max(
|
limit.MAX_EXPRESSION_MS = Math.max(
|
||||||
limit.MAX_EXPRESSION_MS,
|
limit.MAX_EXPRESSION_MS,
|
||||||
newLimit.MAX_EXPRESSION_MS != -1 ? newLimit.MAX_EXPRESSION_MS : Integer.MAX_VALUE
|
newLimit.MAX_EXPRESSION_MS != -1 ? newLimit.MAX_EXPRESSION_MS : Integer.MAX_VALUE
|
||||||
@ -353,6 +363,18 @@ public class Settings extends Config {
|
|||||||
" - History on disk or memory will be deleted",
|
" - History on disk or memory will be deleted",
|
||||||
})
|
})
|
||||||
public int MAX_HISTORY_MB = -1;
|
public int MAX_HISTORY_MB = -1;
|
||||||
|
@Comment({
|
||||||
|
"Sets a maximum limit (in kb) for the size of a player's schematics directory (per-player mode only)",
|
||||||
|
"Set to -1 to disable"
|
||||||
|
})
|
||||||
|
@Migrate("experimental.per-player-file-size-limit")
|
||||||
|
public int SCHEM_FILE_SIZE_LIMIT = -1;
|
||||||
|
@Comment({
|
||||||
|
"Sets a maximum limit for the amount of schematics in a player's schematics directory (per-player mode only)",
|
||||||
|
"Set to -1 to disable"
|
||||||
|
})
|
||||||
|
@Migrate("experimental.per-player-file-num-limit")
|
||||||
|
public int SCHEM_FILE_NUM_LIMIT = -1;
|
||||||
@Comment("Maximum time in milliseconds //calc can execute")
|
@Comment("Maximum time in milliseconds //calc can execute")
|
||||||
public int MAX_EXPRESSION_MS = 50;
|
public int MAX_EXPRESSION_MS = 50;
|
||||||
@Comment({
|
@Comment({
|
||||||
@ -615,18 +637,6 @@ public class Settings extends Config {
|
|||||||
})
|
})
|
||||||
public boolean ALLOW_TICK_FLUIDS = false;
|
public boolean ALLOW_TICK_FLUIDS = false;
|
||||||
|
|
||||||
@Comment({
|
|
||||||
"Sets a maximum limit (in kb) for the size of a player's schematics directory (per-player mode only)",
|
|
||||||
"Set to -1 to disable"
|
|
||||||
})
|
|
||||||
public int PER_PLAYER_FILE_SIZE_LIMIT = -1;
|
|
||||||
|
|
||||||
@Comment({
|
|
||||||
"Sets a maximum limit for the amount of schematics in a player's schematics directory (per-player mode only)",
|
|
||||||
"Set to -1 to disable"
|
|
||||||
})
|
|
||||||
public int PER_PLAYER_FILE_NUM_LIMIT = -1;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Comment({"Web/HTTP connection related settings"})
|
@Comment({"Web/HTTP connection related settings"})
|
||||||
@ -744,4 +754,13 @@ public class Settings extends Config {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class GENERAL {
|
||||||
|
|
||||||
|
@Comment({
|
||||||
|
"If the player should be relocated/unstuck when a generation command would bury them",
|
||||||
|
})
|
||||||
|
public boolean UNSTUCK_ON_GENERATE = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@ public class FaweLimit {
|
|||||||
public int MAX_BLOCKSTATES = 0;
|
public int MAX_BLOCKSTATES = 0;
|
||||||
public int MAX_ENTITIES = 0;
|
public int MAX_ENTITIES = 0;
|
||||||
public int MAX_HISTORY = 0;
|
public int MAX_HISTORY = 0;
|
||||||
|
public int SCHEM_FILE_SIZE_LIMIT = 0;
|
||||||
|
public int SCHEM_FILE_NUM_LIMIT = 0;
|
||||||
public int MAX_EXPRESSION_MS = 0;
|
public int MAX_EXPRESSION_MS = 0;
|
||||||
public int INVENTORY_MODE = Integer.MAX_VALUE;
|
public int INVENTORY_MODE = Integer.MAX_VALUE;
|
||||||
public int SPEED_REDUCTION = Integer.MAX_VALUE;
|
public int SPEED_REDUCTION = Integer.MAX_VALUE;
|
||||||
@ -111,6 +113,8 @@ public class FaweLimit {
|
|||||||
MAX.MAX_BLOCKSTATES = Integer.MAX_VALUE;
|
MAX.MAX_BLOCKSTATES = Integer.MAX_VALUE;
|
||||||
MAX.MAX_ENTITIES = Integer.MAX_VALUE;
|
MAX.MAX_ENTITIES = Integer.MAX_VALUE;
|
||||||
MAX.MAX_HISTORY = Integer.MAX_VALUE;
|
MAX.MAX_HISTORY = Integer.MAX_VALUE;
|
||||||
|
MAX.SCHEM_FILE_NUM_LIMIT = Integer.MAX_VALUE;
|
||||||
|
MAX.SCHEM_FILE_SIZE_LIMIT = Integer.MAX_VALUE;
|
||||||
MAX.MAX_EXPRESSION_MS = 50;
|
MAX.MAX_EXPRESSION_MS = 50;
|
||||||
MAX.FAST_PLACEMENT = true;
|
MAX.FAST_PLACEMENT = true;
|
||||||
MAX.CONFIRM_LARGE = true;
|
MAX.CONFIRM_LARGE = true;
|
||||||
@ -237,6 +241,8 @@ public class FaweLimit {
|
|||||||
&& MAX_BLOCKSTATES == Integer.MAX_VALUE
|
&& MAX_BLOCKSTATES == Integer.MAX_VALUE
|
||||||
&& MAX_ENTITIES == Integer.MAX_VALUE
|
&& MAX_ENTITIES == Integer.MAX_VALUE
|
||||||
&& MAX_HISTORY == Integer.MAX_VALUE
|
&& MAX_HISTORY == Integer.MAX_VALUE
|
||||||
|
&& SCHEM_FILE_SIZE_LIMIT == Integer.MAX_VALUE
|
||||||
|
&& SCHEM_FILE_NUM_LIMIT == Integer.MAX_VALUE
|
||||||
&& INVENTORY_MODE == 0
|
&& INVENTORY_MODE == 0
|
||||||
&& SPEED_REDUCTION == 0
|
&& SPEED_REDUCTION == 0
|
||||||
&& FAST_PLACEMENT
|
&& FAST_PLACEMENT
|
||||||
@ -256,6 +262,8 @@ public class FaweLimit {
|
|||||||
MAX_FAILS = limit.MAX_FAILS;
|
MAX_FAILS = limit.MAX_FAILS;
|
||||||
MAX_ITERATIONS = limit.MAX_ITERATIONS;
|
MAX_ITERATIONS = limit.MAX_ITERATIONS;
|
||||||
MAX_HISTORY = limit.MAX_HISTORY;
|
MAX_HISTORY = limit.MAX_HISTORY;
|
||||||
|
SCHEM_FILE_NUM_LIMIT = limit.SCHEM_FILE_NUM_LIMIT;
|
||||||
|
SCHEM_FILE_SIZE_LIMIT = limit.SCHEM_FILE_SIZE_LIMIT;
|
||||||
INVENTORY_MODE = limit.INVENTORY_MODE;
|
INVENTORY_MODE = limit.INVENTORY_MODE;
|
||||||
SPEED_REDUCTION = limit.SPEED_REDUCTION;
|
SPEED_REDUCTION = limit.SPEED_REDUCTION;
|
||||||
FAST_PLACEMENT = limit.FAST_PLACEMENT;
|
FAST_PLACEMENT = limit.FAST_PLACEMENT;
|
||||||
@ -279,6 +287,8 @@ public class FaweLimit {
|
|||||||
limit.MAX_FAILS = MAX_FAILS;
|
limit.MAX_FAILS = MAX_FAILS;
|
||||||
limit.MAX_ITERATIONS = MAX_ITERATIONS;
|
limit.MAX_ITERATIONS = MAX_ITERATIONS;
|
||||||
limit.MAX_HISTORY = MAX_HISTORY;
|
limit.MAX_HISTORY = MAX_HISTORY;
|
||||||
|
limit.SCHEM_FILE_SIZE_LIMIT = SCHEM_FILE_SIZE_LIMIT;
|
||||||
|
limit.SCHEM_FILE_NUM_LIMIT = SCHEM_FILE_NUM_LIMIT;
|
||||||
limit.FAST_PLACEMENT = FAST_PLACEMENT;
|
limit.FAST_PLACEMENT = FAST_PLACEMENT;
|
||||||
limit.CONFIRM_LARGE = CONFIRM_LARGE;
|
limit.CONFIRM_LARGE = CONFIRM_LARGE;
|
||||||
limit.RESTRICT_HISTORY_TO_REGIONS = RESTRICT_HISTORY_TO_REGIONS;
|
limit.RESTRICT_HISTORY_TO_REGIONS = RESTRICT_HISTORY_TO_REGIONS;
|
||||||
|
@ -23,7 +23,7 @@ import javax.annotation.Nullable;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UncheckedIOException;
|
import java.io.UncheckedIOException;
|
||||||
import java.net.JarURLConnection;
|
import java.net.JarURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URI;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.jar.Attributes;
|
import java.util.jar.Attributes;
|
||||||
import java.util.jar.Manifest;
|
import java.util.jar.Manifest;
|
||||||
@ -73,8 +73,7 @@ public class WorldEditManifest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
URL url = new URL(classPath);
|
JarURLConnection jarConnection = (JarURLConnection) URI.create(classPath).toURL().openConnection();
|
||||||
JarURLConnection jarConnection = (JarURLConnection) url.openConnection();
|
|
||||||
Manifest manifest = jarConnection.getManifest();
|
Manifest manifest = jarConnection.getManifest();
|
||||||
return manifest.getMainAttributes();
|
return manifest.getMainAttributes();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -184,6 +184,9 @@ public class GenerationCommands {
|
|||||||
|
|
||||||
BlockVector3 pos = session.getPlacementPosition(actor);
|
BlockVector3 pos = session.getPlacementPosition(actor);
|
||||||
int affected = editSession.makeCylinder(pos, pattern, radiusX, radiusZ, height, !hollow);
|
int affected = editSession.makeCylinder(pos, pattern, radiusX, radiusZ, height, !hollow);
|
||||||
|
if (actor instanceof Player && Settings.settings().GENERAL.UNSTUCK_ON_GENERATE) {
|
||||||
|
((Player) actor).findFreePosition();
|
||||||
|
}
|
||||||
actor.print(Caption.of("worldedit.cyl.created", TextComponent.of(affected)));
|
actor.print(Caption.of("worldedit.cyl.created", TextComponent.of(affected)));
|
||||||
return affected;
|
return affected;
|
||||||
}
|
}
|
||||||
@ -227,6 +230,9 @@ public class GenerationCommands {
|
|||||||
|
|
||||||
BlockVector3 pos = session.getPlacementPosition(actor);
|
BlockVector3 pos = session.getPlacementPosition(actor);
|
||||||
int affected = editSession.makeCone(pos, pattern, radiusX, radiusZ, height, !hollow, thickness);
|
int affected = editSession.makeCone(pos, pattern, radiusX, radiusZ, height, !hollow, thickness);
|
||||||
|
if (actor instanceof Player && Settings.settings().GENERAL.UNSTUCK_ON_GENERATE) {
|
||||||
|
((Player) actor).findFreePosition();
|
||||||
|
}
|
||||||
actor.printInfo(Caption.of("worldedit.cone.created", TextComponent.of(affected)));
|
actor.printInfo(Caption.of("worldedit.cone.created", TextComponent.of(affected)));
|
||||||
return affected;
|
return affected;
|
||||||
}
|
}
|
||||||
@ -293,7 +299,7 @@ public class GenerationCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int affected = editSession.makeSphere(pos, pattern, radiusX, radiusY, radiusZ, !hollow);
|
int affected = editSession.makeSphere(pos, pattern, radiusX, radiusY, radiusZ, !hollow);
|
||||||
if (actor instanceof Player) {
|
if (actor instanceof Player && Settings.settings().GENERAL.UNSTUCK_ON_GENERATE) {
|
||||||
((Player) actor).findFreePosition();
|
((Player) actor).findFreePosition();
|
||||||
}
|
}
|
||||||
actor.print(Caption.of("worldedit.sphere.created", TextComponent.of(affected)));
|
actor.print(Caption.of("worldedit.sphere.created", TextComponent.of(affected)));
|
||||||
@ -379,7 +385,7 @@ public class GenerationCommands {
|
|||||||
worldEdit.checkMaxRadius(size);
|
worldEdit.checkMaxRadius(size);
|
||||||
BlockVector3 pos = session.getPlacementPosition(actor);
|
BlockVector3 pos = session.getPlacementPosition(actor);
|
||||||
int affected = editSession.makePyramid(pos, pattern, size, !hollow);
|
int affected = editSession.makePyramid(pos, pattern, size, !hollow);
|
||||||
if (actor instanceof Player) {
|
if (actor instanceof Player && Settings.settings().GENERAL.UNSTUCK_ON_GENERATE) {
|
||||||
((Player) actor).findFreePosition();
|
((Player) actor).findFreePosition();
|
||||||
}
|
}
|
||||||
actor.print(Caption.of("worldedit.pyramid.created", TextComponent.of(affected)));
|
actor.print(Caption.of("worldedit.pyramid.created", TextComponent.of(affected)));
|
||||||
@ -457,7 +463,7 @@ public class GenerationCommands {
|
|||||||
hollow,
|
hollow,
|
||||||
session.getTimeout()
|
session.getTimeout()
|
||||||
);
|
);
|
||||||
if (actor instanceof Player) {
|
if (actor instanceof Player && Settings.settings().GENERAL.UNSTUCK_ON_GENERATE) {
|
||||||
((Player) actor).findFreePosition();
|
((Player) actor).findFreePosition();
|
||||||
}
|
}
|
||||||
actor.print(Caption.of("worldedit.generate.created", TextComponent.of(affected)));
|
actor.print(Caption.of("worldedit.generate.created", TextComponent.of(affected)));
|
||||||
@ -741,7 +747,7 @@ public class GenerationCommands {
|
|||||||
radius.divide(max),
|
radius.divide(max),
|
||||||
sphericity / 100
|
sphericity / 100
|
||||||
);
|
);
|
||||||
if (actor instanceof Player) {
|
if (actor instanceof Player && Settings.settings().GENERAL.UNSTUCK_ON_GENERATE) {
|
||||||
((Player) actor).findFreePosition();
|
((Player) actor).findFreePosition();
|
||||||
}
|
}
|
||||||
actor.print(Caption.of("worldedit.sphere.created", TextComponent.of(affected)));
|
actor.print(Caption.of("worldedit.sphere.created", TextComponent.of(affected)));
|
||||||
|
@ -22,6 +22,7 @@ package com.sk89q.worldedit.command;
|
|||||||
import com.fastasyncworldedit.core.FaweAPI;
|
import com.fastasyncworldedit.core.FaweAPI;
|
||||||
import com.fastasyncworldedit.core.FaweCache;
|
import com.fastasyncworldedit.core.FaweCache;
|
||||||
import com.fastasyncworldedit.core.configuration.Caption;
|
import com.fastasyncworldedit.core.configuration.Caption;
|
||||||
|
import com.fastasyncworldedit.core.configuration.Settings;
|
||||||
import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode;
|
import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode;
|
||||||
import com.fastasyncworldedit.core.limit.FaweLimit;
|
import com.fastasyncworldedit.core.limit.FaweLimit;
|
||||||
import com.fastasyncworldedit.core.util.MaskTraverser;
|
import com.fastasyncworldedit.core.util.MaskTraverser;
|
||||||
@ -715,6 +716,9 @@ public class RegionCommands {
|
|||||||
session.setSourceMask(mask);
|
session.setSourceMask(mask);
|
||||||
//FAWE end
|
//FAWE end
|
||||||
}
|
}
|
||||||
|
if (actor instanceof Player && Settings.settings().GENERAL.UNSTUCK_ON_GENERATE) {
|
||||||
|
((Player) actor).findFreePosition();
|
||||||
|
}
|
||||||
if (success) {
|
if (success) {
|
||||||
actor.print(Caption.of("worldedit.regen.regenerated"));
|
actor.print(Caption.of("worldedit.regen.regenerated"));
|
||||||
} else {
|
} else {
|
||||||
@ -788,7 +792,7 @@ public class RegionCommands {
|
|||||||
String.join(" ", expression),
|
String.join(" ", expression),
|
||||||
session.getTimeout()
|
session.getTimeout()
|
||||||
);
|
);
|
||||||
if (actor instanceof Player) {
|
if (actor instanceof Player && Settings.settings().GENERAL.UNSTUCK_ON_GENERATE) {
|
||||||
((Player) actor).findFreePosition();
|
((Player) actor).findFreePosition();
|
||||||
}
|
}
|
||||||
actor.print(Caption.of("worldedit.deform.deformed", TextComponent.of(affected)));
|
actor.print(Caption.of("worldedit.deform.deformed", TextComponent.of(affected)));
|
||||||
|
@ -26,6 +26,7 @@ import com.fastasyncworldedit.core.extent.clipboard.MultiClipboardHolder;
|
|||||||
import com.fastasyncworldedit.core.extent.clipboard.URIClipboardHolder;
|
import com.fastasyncworldedit.core.extent.clipboard.URIClipboardHolder;
|
||||||
import com.fastasyncworldedit.core.extent.clipboard.io.schematic.MinecraftStructure;
|
import com.fastasyncworldedit.core.extent.clipboard.io.schematic.MinecraftStructure;
|
||||||
import com.fastasyncworldedit.core.util.MainUtil;
|
import com.fastasyncworldedit.core.util.MainUtil;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.sk89q.worldedit.LocalConfiguration;
|
import com.sk89q.worldedit.LocalConfiguration;
|
||||||
import com.sk89q.worldedit.LocalSession;
|
import com.sk89q.worldedit.LocalSession;
|
||||||
@ -60,15 +61,19 @@ import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
|||||||
import com.sk89q.worldedit.util.io.Closer;
|
import com.sk89q.worldedit.util.io.Closer;
|
||||||
import com.sk89q.worldedit.util.io.file.FilenameException;
|
import com.sk89q.worldedit.util.io.file.FilenameException;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import com.sk89q.worldedit.util.paste.EngineHubPaste;
|
||||||
|
import com.sk89q.worldedit.util.paste.PasteMetadata;
|
||||||
import org.enginehub.piston.annotation.Command;
|
import org.enginehub.piston.annotation.Command;
|
||||||
import org.enginehub.piston.annotation.CommandContainer;
|
import org.enginehub.piston.annotation.CommandContainer;
|
||||||
import org.enginehub.piston.annotation.param.Arg;
|
import org.enginehub.piston.annotation.param.Arg;
|
||||||
import org.enginehub.piston.annotation.param.ArgFlag;
|
import org.enginehub.piston.annotation.param.ArgFlag;
|
||||||
import org.enginehub.piston.annotation.param.Switch;
|
import org.enginehub.piston.annotation.param.Switch;
|
||||||
|
import org.enginehub.piston.exception.CommandException;
|
||||||
import org.enginehub.piston.exception.StopExecutionException;
|
import org.enginehub.piston.exception.StopExecutionException;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
@ -79,9 +84,12 @@ import java.net.URISyntaxException;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.channels.Channels;
|
import java.nio.channels.Channels;
|
||||||
import java.nio.channels.ReadableByteChannel;
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Base64;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -525,6 +533,42 @@ public class SchematicCommands {
|
|||||||
.buildAndExec(worldEdit.getExecutorService());
|
.buildAndExec(worldEdit.getExecutorService());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Command(
|
||||||
|
name = "share",
|
||||||
|
desc = "Share your clipboard as a schematic online"
|
||||||
|
)
|
||||||
|
@CommandPermissions({ "worldedit.clipboard.share", "worldedit.schematic.share" })
|
||||||
|
public void share(Actor actor, LocalSession session,
|
||||||
|
@Arg(desc = "Schematic name. Defaults to name-millis", def = "")
|
||||||
|
String schematicName,
|
||||||
|
@Arg(desc = "Format name.", def = "sponge")
|
||||||
|
String formatName) throws WorldEditException {
|
||||||
|
if (true) {
|
||||||
|
throw new UnsupportedOperationException("This feature is currently not implemented");
|
||||||
|
}
|
||||||
|
if (worldEdit.getPlatformManager().queryCapability(Capability.GAME_HOOKS).getDataVersion() == -1) {
|
||||||
|
actor.printError(TranslatableComponent.of("worldedit.schematic.unsupported-minecraft-version"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClipboardFormat format = ClipboardFormats.findByAlias(formatName);
|
||||||
|
if (format == null) {
|
||||||
|
actor.printError(TranslatableComponent.of("worldedit.schematic.unknown-format", TextComponent.of(formatName)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClipboardHolder holder = session.getClipboard();
|
||||||
|
|
||||||
|
SchematicShareTask task = new SchematicShareTask(actor, format, holder, schematicName);
|
||||||
|
AsyncCommandBuilder.wrap(task, actor)
|
||||||
|
.registerWithSupervisor(worldEdit.getSupervisor(), "Sharing schematic")
|
||||||
|
.setDelayMessage(TranslatableComponent.of("worldedit.schematic.save.saving"))
|
||||||
|
.setWorkingMessage(TranslatableComponent.of("worldedit.schematic.save.still-saving"))
|
||||||
|
.onSuccess("Shared", (url -> actor.printInfo(TextComponent.of(url.toExternalForm() + ".schem").clickEvent(ClickEvent.openUrl(url.toExternalForm() + ".schem")))))
|
||||||
|
.onFailure("Failed to share schematic", worldEdit.getPlatformManager().getPlatformCommandManager().getExceptionConverter())
|
||||||
|
.buildAndExec(worldEdit.getExecutorService());
|
||||||
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
name = "formats",
|
name = "formats",
|
||||||
aliases = {"listformats", "f"},
|
aliases = {"listformats", "f"},
|
||||||
@ -689,10 +733,10 @@ public class SchematicCommands {
|
|||||||
|
|
||||||
String headerBytesElem = String.format("%.1fkb", totalBytes / 1000.0);
|
String headerBytesElem = String.format("%.1fkb", totalBytes / 1000.0);
|
||||||
|
|
||||||
if (Settings.settings().PATHS.PER_PLAYER_SCHEMATICS && Settings.settings().EXPERIMENTAL.PER_PLAYER_FILE_SIZE_LIMIT > -1) {
|
if (Settings.settings().PATHS.PER_PLAYER_SCHEMATICS && actor.getLimit().SCHEM_FILE_SIZE_LIMIT > -1) {
|
||||||
headerBytesElem += String.format(
|
headerBytesElem += String.format(
|
||||||
" / %dkb",
|
" / %dkb",
|
||||||
Settings.settings().EXPERIMENTAL.PER_PLAYER_FILE_SIZE_LIMIT
|
actor.getLimit().SCHEM_FILE_SIZE_LIMIT
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -793,14 +837,48 @@ public class SchematicCommands {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SchematicSaveTask implements Callable<Void> {
|
private abstract static class SchematicOutputTask<T> implements Callable<T> {
|
||||||
|
protected final Actor actor;
|
||||||
|
protected final ClipboardFormat format;
|
||||||
|
protected final ClipboardHolder holder;
|
||||||
|
|
||||||
private final Actor actor;
|
SchematicOutputTask(
|
||||||
private final ClipboardFormat format;
|
Actor actor,
|
||||||
private final ClipboardHolder holder;
|
ClipboardFormat format,
|
||||||
|
ClipboardHolder holder
|
||||||
|
) {
|
||||||
|
this.actor = actor;
|
||||||
|
this.format = format;
|
||||||
|
this.holder = holder;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void writeToOutputStream(OutputStream outputStream) throws Exception {
|
||||||
|
Clipboard clipboard = holder.getClipboard();
|
||||||
|
Transform transform = holder.getTransform();
|
||||||
|
Clipboard target;
|
||||||
|
// If we have a transform, bake it into the copy
|
||||||
|
if (transform.isIdentity()) {
|
||||||
|
target = clipboard;
|
||||||
|
} else {
|
||||||
|
FlattenedClipboardTransform result = FlattenedClipboardTransform.transform(clipboard, transform);
|
||||||
|
target = new BlockArrayClipboard(result.getTransformedRegion());
|
||||||
|
target.setOrigin(clipboard.getOrigin());
|
||||||
|
Operations.completeLegacy(result.copyTo(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
try (Closer closer = Closer.create()) {
|
||||||
|
OutputStream stream = closer.register(outputStream);
|
||||||
|
BufferedOutputStream bos = closer.register(new BufferedOutputStream(stream));
|
||||||
|
ClipboardWriter writer = closer.register(format.getWriter(bos));
|
||||||
|
writer.write(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SchematicSaveTask extends SchematicOutputTask<Void> {
|
||||||
|
private File file;
|
||||||
private final boolean overwrite;
|
private final boolean overwrite;
|
||||||
private final File rootDir;
|
private final File rootDir;
|
||||||
private File file;
|
|
||||||
|
|
||||||
SchematicSaveTask(
|
SchematicSaveTask(
|
||||||
Actor actor,
|
Actor actor,
|
||||||
@ -810,11 +888,9 @@ public class SchematicCommands {
|
|||||||
ClipboardHolder holder,
|
ClipboardHolder holder,
|
||||||
boolean overwrite
|
boolean overwrite
|
||||||
) {
|
) {
|
||||||
this.actor = actor;
|
super(actor, format, holder);
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.rootDir = rootDir;
|
this.rootDir = rootDir;
|
||||||
this.format = format;
|
|
||||||
this.holder = holder;
|
|
||||||
this.overwrite = overwrite;
|
this.overwrite = overwrite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -826,7 +902,7 @@ public class SchematicCommands {
|
|||||||
|
|
||||||
//FAWE start
|
//FAWE start
|
||||||
boolean checkFilesize = Settings.settings().PATHS.PER_PLAYER_SCHEMATICS
|
boolean checkFilesize = Settings.settings().PATHS.PER_PLAYER_SCHEMATICS
|
||||||
&& Settings.settings().EXPERIMENTAL.PER_PLAYER_FILE_SIZE_LIMIT > -1;
|
&& actor.getLimit().SCHEM_FILE_SIZE_LIMIT > -1;
|
||||||
|
|
||||||
double directorysizeKb = 0;
|
double directorysizeKb = 0;
|
||||||
String curFilepath = file.getAbsolutePath();
|
String curFilepath = file.getAbsolutePath();
|
||||||
@ -856,7 +932,7 @@ public class SchematicCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (Settings.settings().PATHS.PER_PLAYER_SCHEMATICS && Settings.settings().EXPERIMENTAL.PER_PLAYER_FILE_NUM_LIMIT > -1) {
|
if (Settings.settings().PATHS.PER_PLAYER_SCHEMATICS && actor.getLimit().SCHEM_FILE_NUM_LIMIT > -1) {
|
||||||
|
|
||||||
if (numFiles == -1) {
|
if (numFiles == -1) {
|
||||||
numFiles = 0;
|
numFiles = 0;
|
||||||
@ -869,7 +945,7 @@ public class SchematicCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int limit = Settings.settings().EXPERIMENTAL.PER_PLAYER_FILE_NUM_LIMIT;
|
int limit = actor.getLimit().SCHEM_FILE_NUM_LIMIT;
|
||||||
|
|
||||||
if (numFiles >= limit) {
|
if (numFiles >= limit) {
|
||||||
TextComponent noSlotsErr = TextComponent.of( //TODO - to be moved into captions/translatablecomponents
|
TextComponent noSlotsErr = TextComponent.of( //TODO - to be moved into captions/translatablecomponents
|
||||||
@ -920,7 +996,7 @@ public class SchematicCommands {
|
|||||||
if (checkFilesize) {
|
if (checkFilesize) {
|
||||||
|
|
||||||
double curKb = filesizeKb + directorysizeKb;
|
double curKb = filesizeKb + directorysizeKb;
|
||||||
int allocatedKb = Settings.settings().EXPERIMENTAL.PER_PLAYER_FILE_SIZE_LIMIT;
|
int allocatedKb = actor.getLimit().SCHEM_FILE_SIZE_LIMIT;
|
||||||
|
|
||||||
if (overwrite) {
|
if (overwrite) {
|
||||||
curKb -= oldKbOverwritten;
|
curKb -= oldKbOverwritten;
|
||||||
@ -955,11 +1031,11 @@ public class SchematicCommands {
|
|||||||
actor.print(kbRemainingNotif);
|
actor.print(kbRemainingNotif);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Settings.settings().PATHS.PER_PLAYER_SCHEMATICS && Settings.settings().EXPERIMENTAL.PER_PLAYER_FILE_NUM_LIMIT > -1) {
|
if (Settings.settings().PATHS.PER_PLAYER_SCHEMATICS && actor.getLimit().SCHEM_FILE_NUM_LIMIT > -1) {
|
||||||
|
|
||||||
TextComponent slotsRemainingNotif = TextComponent.of(
|
TextComponent slotsRemainingNotif = TextComponent.of(
|
||||||
//TODO - to be moved into captions/translatablecomponents
|
//TODO - to be moved into captions/translatablecomponents
|
||||||
"You have " + (Settings.settings().EXPERIMENTAL.PER_PLAYER_FILE_NUM_LIMIT - numFiles)
|
"You have " + (actor.getLimit().SCHEM_FILE_NUM_LIMIT - numFiles)
|
||||||
+ " schematic file slots left.",
|
+ " schematic file slots left.",
|
||||||
TextColor.GRAY
|
TextColor.GRAY
|
||||||
);
|
);
|
||||||
@ -973,7 +1049,32 @@ public class SchematicCommands {
|
|||||||
//FAWE end
|
//FAWE end
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SchematicShareTask extends SchematicOutputTask<URL> {
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
SchematicShareTask(Actor actor, ClipboardFormat format, ClipboardHolder holder, String name) {
|
||||||
|
super(actor, format, holder);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URL call() throws Exception {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
try {
|
||||||
|
writeToOutputStream(baos);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new CommandException(TextComponent.of(e.getMessage()), e, ImmutableList.of());
|
||||||
|
}
|
||||||
|
|
||||||
|
EngineHubPaste pasteService = new EngineHubPaste();
|
||||||
|
PasteMetadata metadata = new PasteMetadata();
|
||||||
|
metadata.author = this.actor.getName();
|
||||||
|
metadata.extension = "schem";
|
||||||
|
metadata.name = name == null ? actor.getName() + "-" + System.currentTimeMillis() : name;
|
||||||
|
return pasteService.paste(new String(Base64.getEncoder().encode(baos.toByteArray()), StandardCharsets.UTF_8), metadata).call();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SchematicListTask implements Callable<Component> {
|
private static class SchematicListTask implements Callable<Component> {
|
||||||
|
@ -56,6 +56,7 @@ public class BaseEntity implements NbtValued {
|
|||||||
* @param nbtData NBT data
|
* @param nbtData NBT data
|
||||||
* @deprecated Use {@link BaseEntity#BaseEntity(EntityType, LazyReference)}
|
* @deprecated Use {@link BaseEntity#BaseEntity(EntityType, LazyReference)}
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("this-escape")
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public BaseEntity(EntityType type, CompoundTag nbtData) {
|
public BaseEntity(EntityType type, CompoundTag nbtData) {
|
||||||
this(type);
|
this(type);
|
||||||
@ -87,6 +88,7 @@ public class BaseEntity implements NbtValued {
|
|||||||
*
|
*
|
||||||
* @param other the object to clone
|
* @param other the object to clone
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("this-escape")
|
||||||
public BaseEntity(BaseEntity other) {
|
public BaseEntity(BaseEntity other) {
|
||||||
checkNotNull(other);
|
checkNotNull(other);
|
||||||
this.type = other.getType();
|
this.type = other.getType();
|
||||||
|
@ -62,6 +62,7 @@ public class BlockChangeLimiter extends AbstractDelegateExtent {
|
|||||||
*
|
*
|
||||||
* @param limit the limit (>= 0) or -1 for no limit
|
* @param limit the limit (>= 0) or -1 for no limit
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("this-escape") // Unlikely anyone is extending this in practice
|
||||||
public void setLimit(int limit) {
|
public void setLimit(int limit) {
|
||||||
checkArgument(limit >= -1, "limit >= -1 required");
|
checkArgument(limit >= -1, "limit >= -1 required");
|
||||||
this.limit = limit;
|
this.limit = limit;
|
||||||
|
@ -19,11 +19,16 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.util.io;
|
package com.sk89q.worldedit.util.io;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
public class ForwardSeekableInputStream extends InputStream {
|
public class ForwardSeekableInputStream extends InputStream {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
|
||||||
protected InputStream parent;
|
protected InputStream parent;
|
||||||
protected long position = 0;
|
protected long position = 0;
|
||||||
|
|
||||||
@ -60,7 +65,7 @@ public class ForwardSeekableInputStream extends InputStream {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(byte[] b, int off, int len) throws IOException {
|
public int read(byte[] b, int off, int len) throws IOException {
|
||||||
int read = super.read(b, off, len);
|
int read = parent.read(b, off, len);
|
||||||
position += read;
|
position += read;
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
@ -86,6 +91,7 @@ public class ForwardSeekableInputStream extends InputStream {
|
|||||||
|
|
||||||
public void seek(long n) throws IOException {
|
public void seek(long n) throws IOException {
|
||||||
long diff = n - position;
|
long diff = n - position;
|
||||||
|
LOGGER.error("Seek to {} from {} using {}", n, position, diff);
|
||||||
|
|
||||||
if (diff < 0) {
|
if (diff < 0) {
|
||||||
throw new IOException("Can't seek backwards");
|
throw new IOException("Can't seek backwards");
|
||||||
|
@ -357,7 +357,7 @@ public class HttpRequest implements Closeable {
|
|||||||
*/
|
*/
|
||||||
public static URL url(String url) {
|
public static URL url(String url) {
|
||||||
try {
|
try {
|
||||||
return new URL(url);
|
return URI.create(url).toURL();
|
||||||
} catch (MalformedURLException e) {
|
} catch (MalformedURLException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@ -371,13 +371,7 @@ public class HttpRequest implements Closeable {
|
|||||||
*/
|
*/
|
||||||
private static URL reformat(URL existing) {
|
private static URL reformat(URL existing) {
|
||||||
try {
|
try {
|
||||||
URL url = new URL(existing.toString());
|
return existing.toURI().toURL();
|
||||||
URI uri = new URI(
|
|
||||||
url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(),
|
|
||||||
url.getPath(), url.getQuery(), url.getRef()
|
|
||||||
);
|
|
||||||
url = uri.toURL();
|
|
||||||
return url;
|
|
||||||
} catch (MalformedURLException | URISyntaxException e) {
|
} catch (MalformedURLException | URISyntaxException e) {
|
||||||
return existing;
|
return existing;
|
||||||
}
|
}
|
||||||
|
@ -83,4 +83,26 @@ public final class ActorCallbackPaste {
|
|||||||
.buildAndExec(Pasters.getExecutor());
|
.buildAndExec(Pasters.getExecutor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submit data to a pastebin service and inform the sender of
|
||||||
|
* success or failure.
|
||||||
|
*
|
||||||
|
* @param supervisor The supervisor instance
|
||||||
|
* @param sender The sender
|
||||||
|
* @param content The content
|
||||||
|
* @param pasteMetadata The paste metadata
|
||||||
|
* @param successMessage The message builder, given the URL as an arg
|
||||||
|
*/
|
||||||
|
public static void pastebin(Supervisor supervisor, final Actor sender, String content, PasteMetadata pasteMetadata, final TranslatableComponent.Builder successMessage) {
|
||||||
|
Callable<URL> task = paster.paste(content, pasteMetadata);
|
||||||
|
|
||||||
|
AsyncCommandBuilder.wrap(task, sender)
|
||||||
|
.registerWithSupervisor(supervisor, "Submitting content to a pastebin service.")
|
||||||
|
.setDelayMessage(TranslatableComponent.of("worldedit.pastebin.uploading"))
|
||||||
|
.onSuccess((String) null, url -> sender.printInfo(successMessage.args(TextComponent.of(url.toString())).build()))
|
||||||
|
.onFailure("Failed to submit paste", null)
|
||||||
|
.buildAndExec(Pasters.getExecutor());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import com.google.gson.reflect.TypeToken;
|
|||||||
import com.sk89q.worldedit.util.net.HttpRequest;
|
import com.sk89q.worldedit.util.net.HttpRequest;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
@ -33,23 +34,38 @@ public class EngineHubPaste implements Paster {
|
|||||||
private static final Gson GSON = new Gson();
|
private static final Gson GSON = new Gson();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Callable<URL> paste(String content) {
|
public Callable<URL> paste(String content, PasteMetadata metadata) {
|
||||||
return new PasteTask(content);
|
return new PasteTask(content, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class PasteTask implements Callable<URL> {
|
private static final class PasteTask implements Callable<URL> {
|
||||||
|
|
||||||
private final String content;
|
private final String content;
|
||||||
|
private final PasteMetadata metadata;
|
||||||
|
|
||||||
private PasteTask(String content) {
|
private PasteTask(String content, PasteMetadata metadata) {
|
||||||
this.content = content;
|
this.content = content;
|
||||||
|
this.metadata = metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URL call() throws IOException, InterruptedException {
|
public URL call() throws IOException, InterruptedException {
|
||||||
URL initialUrl = HttpRequest.url("https://paste.enginehub.org/signed_paste");
|
URL initialUrl = HttpRequest.url("https://paste.enginehub.org/signed_paste");
|
||||||
|
|
||||||
SignedPasteResponse response = GSON.fromJson(HttpRequest.get(initialUrl)
|
HttpRequest requestBuilder = HttpRequest.get(initialUrl);
|
||||||
|
|
||||||
|
requestBuilder.header("x-paste-meta-from", "EngineHub");
|
||||||
|
if (metadata.name != null) {
|
||||||
|
requestBuilder.header("x-paste-meta-name", metadata.name);
|
||||||
|
}
|
||||||
|
if (metadata.author != null) {
|
||||||
|
requestBuilder.header("x-paste-meta-author", metadata.author);
|
||||||
|
}
|
||||||
|
if (metadata.extension != null) {
|
||||||
|
requestBuilder.header("x-paste-meta-extension", metadata.extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
SignedPasteResponse response = GSON.fromJson(requestBuilder
|
||||||
.execute()
|
.execute()
|
||||||
.expectResponseCode(200)
|
.expectResponseCode(200)
|
||||||
.returnContent()
|
.returnContent()
|
||||||
@ -68,7 +84,7 @@ public class EngineHubPaste implements Paster {
|
|||||||
.execute()
|
.execute()
|
||||||
.expectResponseCode(200, 204);
|
.expectResponseCode(200, 204);
|
||||||
|
|
||||||
return new URL(response.viewUrl);
|
return URI.create(response.viewUrl).toURL();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* 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.sk89q.worldedit.util.paste;
|
||||||
|
|
||||||
|
public class PasteMetadata {
|
||||||
|
public String name;
|
||||||
|
public String extension;
|
||||||
|
public String author;
|
||||||
|
}
|
@ -24,6 +24,10 @@ import java.util.concurrent.Callable;
|
|||||||
|
|
||||||
public interface Paster {
|
public interface Paster {
|
||||||
|
|
||||||
Callable<URL> paste(String content);
|
default Callable<URL> paste(String content) {
|
||||||
|
return paste(content, new PasteMetadata());
|
||||||
|
}
|
||||||
|
|
||||||
|
Callable<URL> paste(String content, PasteMetadata metadata);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -82,21 +82,22 @@ public class FutureForwardingTask<V> extends AbstractTask<V> {
|
|||||||
return future.get(timeout, unit);
|
return future.get(timeout, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: consider deprecating in favor of Future.State?
|
||||||
@Override
|
@Override
|
||||||
public State getState() {
|
public Task.State getState() {
|
||||||
if (isCancelled()) {
|
if (isCancelled()) {
|
||||||
return State.CANCELLED;
|
return Task.State.CANCELLED;
|
||||||
} else if (isDone()) {
|
} else if (isDone()) {
|
||||||
try {
|
try {
|
||||||
get();
|
get();
|
||||||
return State.SUCCEEDED;
|
return Task.State.SUCCEEDED;
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
return State.CANCELLED;
|
return Task.State.CANCELLED;
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
return State.FAILED;
|
return Task.State.FAILED;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return State.RUNNING;
|
return Task.State.RUNNING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,8 +33,10 @@ public final class BlockCategories {
|
|||||||
public static final BlockCategory ANCIENT_CITY_REPLACEABLE = get("minecraft:ancient_city_replaceable");
|
public static final BlockCategory ANCIENT_CITY_REPLACEABLE = get("minecraft:ancient_city_replaceable");
|
||||||
public static final BlockCategory ANIMALS_SPAWNABLE_ON = get("minecraft:animals_spawnable_on");
|
public static final BlockCategory ANIMALS_SPAWNABLE_ON = get("minecraft:animals_spawnable_on");
|
||||||
public static final BlockCategory ANVIL = get("minecraft:anvil");
|
public static final BlockCategory ANVIL = get("minecraft:anvil");
|
||||||
|
public static final BlockCategory ARMADILLO_SPAWNABLE_ON = get("minecraft:armadillo_spawnable_on");
|
||||||
public static final BlockCategory AXOLOTLS_SPAWNABLE_ON = get("minecraft:axolotls_spawnable_on");
|
public static final BlockCategory AXOLOTLS_SPAWNABLE_ON = get("minecraft:axolotls_spawnable_on");
|
||||||
public static final BlockCategory AZALEA_GROWS_ON = get("minecraft:azalea_grows_on");
|
public static final BlockCategory AZALEA_GROWS_ON = get("minecraft:azalea_grows_on");
|
||||||
|
public static final BlockCategory BADLANDS_TERRACOTTA = get("minecraft:badlands_terracotta");
|
||||||
public static final BlockCategory AZALEA_ROOT_REPLACEABLE = get("minecraft:azalea_root_replaceable");
|
public static final BlockCategory AZALEA_ROOT_REPLACEABLE = get("minecraft:azalea_root_replaceable");
|
||||||
public static final BlockCategory BAMBOO_BLOCKS = get("minecraft:bamboo_blocks");
|
public static final BlockCategory BAMBOO_BLOCKS = get("minecraft:bamboo_blocks");
|
||||||
public static final BlockCategory BAMBOO_PLANTABLE_ON = get("minecraft:bamboo_plantable_on");
|
public static final BlockCategory BAMBOO_PLANTABLE_ON = get("minecraft:bamboo_plantable_on");
|
||||||
@ -78,6 +80,7 @@ public final class BlockCategories {
|
|||||||
public static final BlockCategory DIRT = get("minecraft:dirt");
|
public static final BlockCategory DIRT = get("minecraft:dirt");
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static final BlockCategory DIRT_LIKE = get("minecraft:dirt_like");
|
public static final BlockCategory DIRT_LIKE = get("minecraft:dirt_like");
|
||||||
|
public static final BlockCategory DOES_NOT_BLOCK_HOPPERS = get("minecraft:does_not_block_hoppers");
|
||||||
public static final BlockCategory DOORS = get("minecraft:doors");
|
public static final BlockCategory DOORS = get("minecraft:doors");
|
||||||
public static final BlockCategory DRAGON_IMMUNE = get("minecraft:dragon_immune");
|
public static final BlockCategory DRAGON_IMMUNE = get("minecraft:dragon_immune");
|
||||||
public static final BlockCategory DRAGON_TRANSPARENT = get("minecraft:dragon_transparent");
|
public static final BlockCategory DRAGON_TRANSPARENT = get("minecraft:dragon_transparent");
|
||||||
@ -103,6 +106,12 @@ public final class BlockCategories {
|
|||||||
public static final BlockCategory HOGLIN_REPELLENTS = get("minecraft:hoglin_repellents");
|
public static final BlockCategory HOGLIN_REPELLENTS = get("minecraft:hoglin_repellents");
|
||||||
public static final BlockCategory ICE = get("minecraft:ice");
|
public static final BlockCategory ICE = get("minecraft:ice");
|
||||||
public static final BlockCategory IMPERMEABLE = get("minecraft:impermeable");
|
public static final BlockCategory IMPERMEABLE = get("minecraft:impermeable");
|
||||||
|
public static final BlockCategory INCORRECT_FOR_DIAMOND_TOOL = get("minecraft:incorrect_for_diamond_tool");
|
||||||
|
public static final BlockCategory INCORRECT_FOR_GOLD_TOOL = get("minecraft:incorrect_for_gold_tool");
|
||||||
|
public static final BlockCategory INCORRECT_FOR_IRON_TOOL = get("minecraft:incorrect_for_iron_tool");
|
||||||
|
public static final BlockCategory INCORRECT_FOR_NETHERITE_TOOL = get("minecraft:incorrect_for_netherite_tool");
|
||||||
|
public static final BlockCategory INCORRECT_FOR_STONE_TOOL = get("minecraft:incorrect_for_stone_tool");
|
||||||
|
public static final BlockCategory INCORRECT_FOR_WOODEN_TOOL = get("minecraft:incorrect_for_wooden_tool");
|
||||||
public static final BlockCategory INFINIBURN_END = get("minecraft:infiniburn_end");
|
public static final BlockCategory INFINIBURN_END = get("minecraft:infiniburn_end");
|
||||||
public static final BlockCategory INFINIBURN_NETHER = get("minecraft:infiniburn_nether");
|
public static final BlockCategory INFINIBURN_NETHER = get("minecraft:infiniburn_nether");
|
||||||
public static final BlockCategory INFINIBURN_OVERWORLD = get("minecraft:infiniburn_overworld");
|
public static final BlockCategory INFINIBURN_OVERWORLD = get("minecraft:infiniburn_overworld");
|
||||||
|
@ -60,6 +60,7 @@ public class BlockType implements Keyed, Pattern {
|
|||||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
|
@SuppressWarnings("this-escape")
|
||||||
private final LazyReference<FuzzyBlockState> emptyFuzzy
|
private final LazyReference<FuzzyBlockState> emptyFuzzy
|
||||||
= LazyReference.from(() -> new FuzzyBlockState(this));
|
= LazyReference.from(() -> new FuzzyBlockState(this));
|
||||||
//FAWE start
|
//FAWE start
|
||||||
|
@ -483,6 +483,10 @@ public final class BlockTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType COPPER_GRATE = init();
|
public static final BlockType COPPER_GRATE = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final BlockType COPPER_ORE = init();
|
||||||
|
@Nullable
|
||||||
|
public static final BlockType COPPER_TRAPDOOR = init();
|
||||||
|
@Nullable
|
||||||
public static final BlockType CORNFLOWER = init();
|
public static final BlockType CORNFLOWER = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType CRACKED_DEEPSLATE_BRICKS = init();
|
public static final BlockType CRACKED_DEEPSLATE_BRICKS = init();
|
||||||
@ -495,6 +499,8 @@ public final class BlockTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType CRACKED_STONE_BRICKS = init();
|
public static final BlockType CRACKED_STONE_BRICKS = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final BlockType CRAFTER = init();
|
||||||
|
@Nullable
|
||||||
public static final BlockType CRAFTING_TABLE = init();
|
public static final BlockType CRAFTING_TABLE = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType CREEPER_HEAD = init();
|
public static final BlockType CREEPER_HEAD = init();
|
||||||
@ -685,8 +691,6 @@ public final class BlockTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType DEEPSLATE_COPPER_ORE = init();
|
public static final BlockType DEEPSLATE_COPPER_ORE = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType COPPER_TRAPDOOR = init();
|
|
||||||
@Nullable
|
|
||||||
public static final BlockType DEEPSLATE_DIAMOND_ORE = init();
|
public static final BlockType DEEPSLATE_DIAMOND_ORE = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType DEEPSLATE_EMERALD_ORE = init();
|
public static final BlockType DEEPSLATE_EMERALD_ORE = init();
|
||||||
@ -747,8 +751,6 @@ public final class BlockTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType ENDER_CHEST = init();
|
public static final BlockType ENDER_CHEST = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType EXPOSED_CHISELED_COPPER = init();
|
|
||||||
@Nullable
|
|
||||||
public static final BlockType END_GATEWAY = init();
|
public static final BlockType END_GATEWAY = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType END_PORTAL = init();
|
public static final BlockType END_PORTAL = init();
|
||||||
@ -767,6 +769,8 @@ public final class BlockTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType END_STONE_BRICK_WALL = init();
|
public static final BlockType END_STONE_BRICK_WALL = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final BlockType EXPOSED_CHISELED_COPPER = init();
|
||||||
|
@Nullable
|
||||||
public static final BlockType EXPOSED_COPPER = init();
|
public static final BlockType EXPOSED_COPPER = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType EXPOSED_COPPER_BULB = init();
|
public static final BlockType EXPOSED_COPPER_BULB = init();
|
||||||
@ -836,6 +840,9 @@ public final class BlockTypes {
|
|||||||
public static final BlockType GRASS = init();
|
public static final BlockType GRASS = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType GRASS_BLOCK = init();
|
public static final BlockType GRASS_BLOCK = init();
|
||||||
|
@Deprecated
|
||||||
|
@Nullable
|
||||||
|
public static final BlockType GRASS_PATH = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType GRAVEL = init();
|
public static final BlockType GRAVEL = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -901,6 +908,8 @@ public final class BlockTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType HAY_BLOCK = init();
|
public static final BlockType HAY_BLOCK = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final BlockType HEAVY_CORE = init();
|
||||||
|
@Nullable
|
||||||
public static final BlockType HEAVY_WEIGHTED_PRESSURE_PLATE = init();
|
public static final BlockType HEAVY_WEIGHTED_PRESSURE_PLATE = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType HONEYCOMB_BLOCK = init();
|
public static final BlockType HONEYCOMB_BLOCK = init();
|
||||||
@ -925,8 +934,6 @@ public final class BlockTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType INFESTED_CRACKED_STONE_BRICKS = init();
|
public static final BlockType INFESTED_CRACKED_STONE_BRICKS = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType CRAFTER = init();
|
|
||||||
@Nullable
|
|
||||||
public static final BlockType INFESTED_DEEPSLATE = init();
|
public static final BlockType INFESTED_DEEPSLATE = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType INFESTED_MOSSY_STONE_BRICKS = init();
|
public static final BlockType INFESTED_MOSSY_STONE_BRICKS = init();
|
||||||
@ -1954,10 +1961,12 @@ public final class BlockTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType TWISTING_VINES = init();
|
public static final BlockType TWISTING_VINES = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType VERDANT_FROGLIGHT = init();
|
|
||||||
@Nullable
|
|
||||||
public static final BlockType TWISTING_VINES_PLANT = init();
|
public static final BlockType TWISTING_VINES_PLANT = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final BlockType VAULT = init();
|
||||||
|
@Nullable
|
||||||
|
public static final BlockType VERDANT_FROGLIGHT = init();
|
||||||
|
@Nullable
|
||||||
public static final BlockType VINE = init();
|
public static final BlockType VINE = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final BlockType VOID_AIR = init();
|
public static final BlockType VOID_AIR = init();
|
||||||
|
@ -163,7 +163,7 @@ public class AnvilChunk13 implements Chunk {
|
|||||||
throw new InvalidFormatException("Too short block state table");
|
throw new InvalidFormatException("Too short block state table");
|
||||||
}
|
}
|
||||||
currentSerializedValue = blockStatesSerialized[nextSerializedItem++];
|
currentSerializedValue = blockStatesSerialized[nextSerializedItem++];
|
||||||
localBlockId |= (currentSerializedValue & ((1 << bitsNextLong) - 1)) << remainingBits;
|
localBlockId |= (int) ((currentSerializedValue & ((1 << bitsNextLong) - 1)) << remainingBits);
|
||||||
currentSerializedValue >>>= bitsNextLong;
|
currentSerializedValue >>>= bitsNextLong;
|
||||||
remainingBits = 64 - bitsNextLong;
|
remainingBits = 64 - bitsNextLong;
|
||||||
} else {
|
} else {
|
||||||
|
@ -35,6 +35,8 @@ public final class EntityTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final EntityType AREA_EFFECT_CLOUD = get("minecraft:area_effect_cloud");
|
public static final EntityType AREA_EFFECT_CLOUD = get("minecraft:area_effect_cloud");
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final EntityType ARMADILLO = get("minecraft:armadillo");
|
||||||
|
@Nullable
|
||||||
public static final EntityType ARMOR_STAND = get("minecraft:armor_stand");
|
public static final EntityType ARMOR_STAND = get("minecraft:armor_stand");
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final EntityType ARROW = get("minecraft:arrow");
|
public static final EntityType ARROW = get("minecraft:arrow");
|
||||||
@ -51,8 +53,12 @@ public final class EntityTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final EntityType BOAT = get("minecraft:boat");
|
public static final EntityType BOAT = get("minecraft:boat");
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final EntityType BOGGED = get("minecraft:bogged");
|
||||||
|
@Nullable
|
||||||
public static final EntityType BREEZE = get("minecraft:breeze");
|
public static final EntityType BREEZE = get("minecraft:breeze");
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final EntityType BREEZE_WIND_CHARGE = get("minecraft:breeze_wind_charge");
|
||||||
|
@Nullable
|
||||||
public static final EntityType CAMEL = get("minecraft:camel");
|
public static final EntityType CAMEL = get("minecraft:camel");
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final EntityType CAT = get("minecraft:cat");
|
public static final EntityType CAT = get("minecraft:cat");
|
||||||
@ -171,6 +177,8 @@ public final class EntityTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final EntityType OCELOT = get("minecraft:ocelot");
|
public static final EntityType OCELOT = get("minecraft:ocelot");
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final EntityType OMINOUS_ITEM_SPAWNER = get("minecraft:ominous_item_spawner");
|
||||||
|
@Nullable
|
||||||
public static final EntityType PAINTING = get("minecraft:painting");
|
public static final EntityType PAINTING = get("minecraft:painting");
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final EntityType PANDA = get("minecraft:panda");
|
public static final EntityType PANDA = get("minecraft:panda");
|
||||||
|
@ -29,28 +29,36 @@ public final class ItemCategories {
|
|||||||
|
|
||||||
public static final ItemCategory ACACIA_LOGS = get("minecraft:acacia_logs");
|
public static final ItemCategory ACACIA_LOGS = get("minecraft:acacia_logs");
|
||||||
public static final ItemCategory ANVIL = get("minecraft:anvil");
|
public static final ItemCategory ANVIL = get("minecraft:anvil");
|
||||||
|
public static final ItemCategory ARMADILLO_FOOD = get("minecraft:armadillo_food");
|
||||||
public static final ItemCategory ARROWS = get("minecraft:arrows");
|
public static final ItemCategory ARROWS = get("minecraft:arrows");
|
||||||
public static final ItemCategory AXES = get("minecraft:axes");
|
public static final ItemCategory AXES = get("minecraft:axes");
|
||||||
public static final ItemCategory AXOLOTL_TEMPT_ITEMS = get("minecraft:axolotl_tempt_items");
|
public static final ItemCategory AXOLOTL_FOOD = get("minecraft:axolotl_food");
|
||||||
|
@Deprecated public static final ItemCategory AXOLOTL_TEMPT_ITEMS = get("minecraft:axolotl_tempt_items");
|
||||||
public static final ItemCategory BAMBOO_BLOCKS = get("minecraft:bamboo_blocks");
|
public static final ItemCategory BAMBOO_BLOCKS = get("minecraft:bamboo_blocks");
|
||||||
public static final ItemCategory BANNERS = get("minecraft:banners");
|
public static final ItemCategory BANNERS = get("minecraft:banners");
|
||||||
public static final ItemCategory BEACON_PAYMENT_ITEMS = get("minecraft:beacon_payment_items");
|
public static final ItemCategory BEACON_PAYMENT_ITEMS = get("minecraft:beacon_payment_items");
|
||||||
public static final ItemCategory BEDS = get("minecraft:beds");
|
public static final ItemCategory BEDS = get("minecraft:beds");
|
||||||
|
public static final ItemCategory BEE_FOOD = get("minecraft:bee_food");
|
||||||
public static final ItemCategory BIRCH_LOGS = get("minecraft:birch_logs");
|
public static final ItemCategory BIRCH_LOGS = get("minecraft:birch_logs");
|
||||||
public static final ItemCategory BOATS = get("minecraft:boats");
|
public static final ItemCategory BOATS = get("minecraft:boats");
|
||||||
public static final ItemCategory BOOKSHELF_BOOKS = get("minecraft:bookshelf_books");
|
public static final ItemCategory BOOKSHELF_BOOKS = get("minecraft:bookshelf_books");
|
||||||
public static final ItemCategory BREAKS_DECORATED_POTS = get("minecraft:breaks_decorated_pots");
|
public static final ItemCategory BREAKS_DECORATED_POTS = get("minecraft:breaks_decorated_pots");
|
||||||
public static final ItemCategory BUTTONS = get("minecraft:buttons");
|
public static final ItemCategory BUTTONS = get("minecraft:buttons");
|
||||||
|
public static final ItemCategory CAMEL_FOOD = get("minecraft:camel_food");
|
||||||
public static final ItemCategory CANDLES = get("minecraft:candles");
|
public static final ItemCategory CANDLES = get("minecraft:candles");
|
||||||
@Deprecated public static final ItemCategory CARPETS = get("minecraft:carpets");
|
@Deprecated public static final ItemCategory CARPETS = get("minecraft:carpets");
|
||||||
|
public static final ItemCategory CAT_FOOD = get("minecraft:cat_food");
|
||||||
public static final ItemCategory CHERRY_LOGS = get("minecraft:cherry_logs");
|
public static final ItemCategory CHERRY_LOGS = get("minecraft:cherry_logs");
|
||||||
|
public static final ItemCategory CHEST_ARMOR = get("minecraft:chest_armor");
|
||||||
public static final ItemCategory CHEST_BOATS = get("minecraft:chest_boats");
|
public static final ItemCategory CHEST_BOATS = get("minecraft:chest_boats");
|
||||||
|
public static final ItemCategory CHICKEN_FOOD = get("minecraft:chicken_food");
|
||||||
public static final ItemCategory CLUSTER_MAX_HARVESTABLES = get("minecraft:cluster_max_harvestables");
|
public static final ItemCategory CLUSTER_MAX_HARVESTABLES = get("minecraft:cluster_max_harvestables");
|
||||||
public static final ItemCategory COAL_ORES = get("minecraft:coal_ores");
|
public static final ItemCategory COAL_ORES = get("minecraft:coal_ores");
|
||||||
public static final ItemCategory COALS = get("minecraft:coals");
|
public static final ItemCategory COALS = get("minecraft:coals");
|
||||||
public static final ItemCategory COMPASSES = get("minecraft:compasses");
|
public static final ItemCategory COMPASSES = get("minecraft:compasses");
|
||||||
public static final ItemCategory COMPLETES_FIND_TREE_TUTORIAL = get("minecraft:completes_find_tree_tutorial");
|
public static final ItemCategory COMPLETES_FIND_TREE_TUTORIAL = get("minecraft:completes_find_tree_tutorial");
|
||||||
public static final ItemCategory COPPER_ORES = get("minecraft:copper_ores");
|
public static final ItemCategory COPPER_ORES = get("minecraft:copper_ores");
|
||||||
|
public static final ItemCategory COW_FOOD = get("minecraft:cow_food");
|
||||||
public static final ItemCategory CREEPER_DROP_MUSIC_DISCS = get("minecraft:creeper_drop_music_discs");
|
public static final ItemCategory CREEPER_DROP_MUSIC_DISCS = get("minecraft:creeper_drop_music_discs");
|
||||||
public static final ItemCategory CREEPER_IGNITERS = get("minecraft:creeper_igniters");
|
public static final ItemCategory CREEPER_IGNITERS = get("minecraft:creeper_igniters");
|
||||||
public static final ItemCategory CRIMSON_STEMS = get("minecraft:crimson_stems");
|
public static final ItemCategory CRIMSON_STEMS = get("minecraft:crimson_stems");
|
||||||
@ -61,44 +69,82 @@ public final class ItemCategories {
|
|||||||
public static final ItemCategory DIAMOND_ORES = get("minecraft:diamond_ores");
|
public static final ItemCategory DIAMOND_ORES = get("minecraft:diamond_ores");
|
||||||
public static final ItemCategory DIRT = get("minecraft:dirt");
|
public static final ItemCategory DIRT = get("minecraft:dirt");
|
||||||
public static final ItemCategory DOORS = get("minecraft:doors");
|
public static final ItemCategory DOORS = get("minecraft:doors");
|
||||||
|
public static final ItemCategory DYEABLE = get("minecraft:dyeable");
|
||||||
public static final ItemCategory EMERALD_ORES = get("minecraft:emerald_ores");
|
public static final ItemCategory EMERALD_ORES = get("minecraft:emerald_ores");
|
||||||
|
public static final ItemCategory ENCHANTABLE_ARMOR = get("minecraft:enchantable/armor");
|
||||||
|
public static final ItemCategory ENCHANTABLE_BOW = get("minecraft:enchantable/bow");
|
||||||
|
public static final ItemCategory ENCHANTABLE_CHEST_ARMOR = get("minecraft:enchantable/chest_armor");
|
||||||
|
public static final ItemCategory ENCHANTABLE_CROSSBOW = get("minecraft:enchantable/crossbow");
|
||||||
|
public static final ItemCategory ENCHANTABLE_DURABILITY = get("minecraft:enchantable/durability");
|
||||||
|
public static final ItemCategory ENCHANTABLE_EQUIPPABLE = get("minecraft:enchantable/equippable");
|
||||||
|
public static final ItemCategory ENCHANTABLE_FIRE_ASPECT = get("minecraft:enchantable/fire_aspect");
|
||||||
|
public static final ItemCategory ENCHANTABLE_FISHING = get("minecraft:enchantable/fishing");
|
||||||
|
public static final ItemCategory ENCHANTABLE_FOOT_ARMOR = get("minecraft:enchantable/foot_armor");
|
||||||
|
public static final ItemCategory ENCHANTABLE_HEAD_ARMOR = get("minecraft:enchantable/head_armor");
|
||||||
|
public static final ItemCategory ENCHANTABLE_LEG_ARMOR = get("minecraft:enchantable/leg_armor");
|
||||||
|
public static final ItemCategory ENCHANTABLE_MINING = get("minecraft:enchantable/mining");
|
||||||
|
public static final ItemCategory ENCHANTABLE_MINING_LOOT = get("minecraft:enchantable/mining_loot");
|
||||||
|
public static final ItemCategory ENCHANTABLE_SHARP_WEAPON = get("minecraft:enchantable/sharp_weapon");
|
||||||
|
public static final ItemCategory ENCHANTABLE_SWORD = get("minecraft:enchantable/sword");
|
||||||
|
public static final ItemCategory ENCHANTABLE_TRIDENT = get("minecraft:enchantable/trident");
|
||||||
|
public static final ItemCategory ENCHANTABLE_VANISHING = get("minecraft:enchantable/vanishing");
|
||||||
|
public static final ItemCategory ENCHANTABLE_WEAPON = get("minecraft:enchantable/weapon");
|
||||||
public static final ItemCategory FENCE_GATES = get("minecraft:fence_gates");
|
public static final ItemCategory FENCE_GATES = get("minecraft:fence_gates");
|
||||||
public static final ItemCategory FENCES = get("minecraft:fences");
|
public static final ItemCategory FENCES = get("minecraft:fences");
|
||||||
public static final ItemCategory FISHES = get("minecraft:fishes");
|
public static final ItemCategory FISHES = get("minecraft:fishes");
|
||||||
public static final ItemCategory FLOWERS = get("minecraft:flowers");
|
public static final ItemCategory FLOWERS = get("minecraft:flowers");
|
||||||
|
public static final ItemCategory FOOT_ARMOR = get("minecraft:foot_armor");
|
||||||
public static final ItemCategory FOX_FOOD = get("minecraft:fox_food");
|
public static final ItemCategory FOX_FOOD = get("minecraft:fox_food");
|
||||||
public static final ItemCategory FREEZE_IMMUNE_WEARABLES = get("minecraft:freeze_immune_wearables");
|
public static final ItemCategory FREEZE_IMMUNE_WEARABLES = get("minecraft:freeze_immune_wearables");
|
||||||
|
public static final ItemCategory FROG_FOOD = get("minecraft:frog_food");
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static final ItemCategory FURNACE_MATERIALS = get("minecraft:furnace_materials");
|
public static final ItemCategory FURNACE_MATERIALS = get("minecraft:furnace_materials");
|
||||||
|
public static final ItemCategory GOAT_FOOD = get("minecraft:goat_food");
|
||||||
public static final ItemCategory GOLD_ORES = get("minecraft:gold_ores");
|
public static final ItemCategory GOLD_ORES = get("minecraft:gold_ores");
|
||||||
public static final ItemCategory HANGING_SIGNS = get("minecraft:hanging_signs");
|
public static final ItemCategory HANGING_SIGNS = get("minecraft:hanging_signs");
|
||||||
|
public static final ItemCategory HEAD_ARMOR = get("minecraft:head_armor");
|
||||||
public static final ItemCategory HOES = get("minecraft:hoes");
|
public static final ItemCategory HOES = get("minecraft:hoes");
|
||||||
|
public static final ItemCategory HOGLIN_FOOD = get("minecraft:hoglin_food");
|
||||||
|
public static final ItemCategory HORSE_FOOD = get("minecraft:horse_food");
|
||||||
|
public static final ItemCategory HORSE_TEMPT_ITEMS = get("minecraft:horse_tempt_items");
|
||||||
public static final ItemCategory IGNORED_BY_PIGLIN_BABIES = get("minecraft:ignored_by_piglin_babies");
|
public static final ItemCategory IGNORED_BY_PIGLIN_BABIES = get("minecraft:ignored_by_piglin_babies");
|
||||||
public static final ItemCategory IRON_ORES = get("minecraft:iron_ores");
|
public static final ItemCategory IRON_ORES = get("minecraft:iron_ores");
|
||||||
public static final ItemCategory JUNGLE_LOGS = get("minecraft:jungle_logs");
|
public static final ItemCategory JUNGLE_LOGS = get("minecraft:jungle_logs");
|
||||||
public static final ItemCategory LAPIS_ORES = get("minecraft:lapis_ores");
|
public static final ItemCategory LAPIS_ORES = get("minecraft:lapis_ores");
|
||||||
public static final ItemCategory LEAVES = get("minecraft:leaves");
|
public static final ItemCategory LEAVES = get("minecraft:leaves");
|
||||||
public static final ItemCategory LECTERN_BOOKS = get("minecraft:lectern_books");
|
public static final ItemCategory LECTERN_BOOKS = get("minecraft:lectern_books");
|
||||||
|
public static final ItemCategory LEG_ARMOR = get("minecraft:leg_armor");
|
||||||
|
public static final ItemCategory LLAMA_FOOD = get("minecraft:llama_food");
|
||||||
|
public static final ItemCategory LLAMA_TEMPT_ITEMS = get("minecraft:llama_tempt_items");
|
||||||
public static final ItemCategory LOGS = get("minecraft:logs");
|
public static final ItemCategory LOGS = get("minecraft:logs");
|
||||||
public static final ItemCategory LOGS_THAT_BURN = get("minecraft:logs_that_burn");
|
public static final ItemCategory LOGS_THAT_BURN = get("minecraft:logs_that_burn");
|
||||||
public static final ItemCategory MANGROVE_LOGS = get("minecraft:mangrove_logs");
|
public static final ItemCategory MANGROVE_LOGS = get("minecraft:mangrove_logs");
|
||||||
|
public static final ItemCategory MEAT = get("minecraft:meat");
|
||||||
public static final ItemCategory MUSIC_DISCS = get("minecraft:music_discs");
|
public static final ItemCategory MUSIC_DISCS = get("minecraft:music_discs");
|
||||||
public static final ItemCategory NON_FLAMMABLE_WOOD = get("minecraft:non_flammable_wood");
|
public static final ItemCategory NON_FLAMMABLE_WOOD = get("minecraft:non_flammable_wood");
|
||||||
public static final ItemCategory NOTEBLOCK_TOP_INSTRUMENTS = get("minecraft:noteblock_top_instruments");
|
public static final ItemCategory NOTEBLOCK_TOP_INSTRUMENTS = get("minecraft:noteblock_top_instruments");
|
||||||
public static final ItemCategory OAK_LOGS = get("minecraft:oak_logs");
|
public static final ItemCategory OAK_LOGS = get("minecraft:oak_logs");
|
||||||
@Deprecated public static final ItemCategory OCCLUDES_VIBRATION_SIGNALS = get("minecraft:occludes_vibration_signals");
|
@Deprecated public static final ItemCategory OCCLUDES_VIBRATION_SIGNALS = get("minecraft:occludes_vibration_signals");
|
||||||
|
public static final ItemCategory OCELOT_FOOD = get("minecraft:ocelot_food");
|
||||||
@Deprecated public static final ItemCategory OVERWORLD_NATURAL_LOGS = get("minecraft:overworld_natural_logs");
|
@Deprecated public static final ItemCategory OVERWORLD_NATURAL_LOGS = get("minecraft:overworld_natural_logs");
|
||||||
|
public static final ItemCategory PANDA_FOOD = get("minecraft:panda_food");
|
||||||
|
public static final ItemCategory PARROT_FOOD = get("minecraft:parrot_food");
|
||||||
|
public static final ItemCategory PARROT_POISONOUS_FOOD = get("minecraft:parrot_poisonous_food");
|
||||||
public static final ItemCategory PICKAXES = get("minecraft:pickaxes");
|
public static final ItemCategory PICKAXES = get("minecraft:pickaxes");
|
||||||
|
public static final ItemCategory PIG_FOOD = get("minecraft:pig_food");
|
||||||
public static final ItemCategory PIGLIN_FOOD = get("minecraft:piglin_food");
|
public static final ItemCategory PIGLIN_FOOD = get("minecraft:piglin_food");
|
||||||
public static final ItemCategory PIGLIN_LOVED = get("minecraft:piglin_loved");
|
public static final ItemCategory PIGLIN_LOVED = get("minecraft:piglin_loved");
|
||||||
public static final ItemCategory PIGLIN_REPELLENTS = get("minecraft:piglin_repellents");
|
public static final ItemCategory PIGLIN_REPELLENTS = get("minecraft:piglin_repellents");
|
||||||
public static final ItemCategory PLANKS = get("minecraft:planks");
|
public static final ItemCategory PLANKS = get("minecraft:planks");
|
||||||
|
public static final ItemCategory RABBIT_FOOD = get("minecraft:rabbit_food");
|
||||||
public static final ItemCategory RAILS = get("minecraft:rails");
|
public static final ItemCategory RAILS = get("minecraft:rails");
|
||||||
public static final ItemCategory REDSTONE_ORES = get("minecraft:redstone_ores");
|
public static final ItemCategory REDSTONE_ORES = get("minecraft:redstone_ores");
|
||||||
public static final ItemCategory SAND = get("minecraft:sand");
|
public static final ItemCategory SAND = get("minecraft:sand");
|
||||||
public static final ItemCategory SAPLINGS = get("minecraft:saplings");
|
public static final ItemCategory SAPLINGS = get("minecraft:saplings");
|
||||||
|
public static final ItemCategory SHEEP_FOOD = get("minecraft:sheep_food");
|
||||||
public static final ItemCategory SHOVELS = get("minecraft:shovels");
|
public static final ItemCategory SHOVELS = get("minecraft:shovels");
|
||||||
public static final ItemCategory SIGNS = get("minecraft:signs");
|
public static final ItemCategory SIGNS = get("minecraft:signs");
|
||||||
|
public static final ItemCategory SKULLS = get("minecraft:skulls");
|
||||||
public static final ItemCategory SLABS = get("minecraft:slabs");
|
public static final ItemCategory SLABS = get("minecraft:slabs");
|
||||||
public static final ItemCategory SMALL_FLOWERS = get("minecraft:small_flowers");
|
public static final ItemCategory SMALL_FLOWERS = get("minecraft:small_flowers");
|
||||||
public static final ItemCategory SMELTS_TO_GLASS = get("minecraft:smelts_to_glass");
|
public static final ItemCategory SMELTS_TO_GLASS = get("minecraft:smelts_to_glass");
|
||||||
@ -110,18 +156,22 @@ public final class ItemCategories {
|
|||||||
public static final ItemCategory STONE_BUTTONS = get("minecraft:stone_buttons");
|
public static final ItemCategory STONE_BUTTONS = get("minecraft:stone_buttons");
|
||||||
public static final ItemCategory STONE_CRAFTING_MATERIALS = get("minecraft:stone_crafting_materials");
|
public static final ItemCategory STONE_CRAFTING_MATERIALS = get("minecraft:stone_crafting_materials");
|
||||||
public static final ItemCategory STONE_TOOL_MATERIALS = get("minecraft:stone_tool_materials");
|
public static final ItemCategory STONE_TOOL_MATERIALS = get("minecraft:stone_tool_materials");
|
||||||
|
public static final ItemCategory STRIDER_FOOD = get("minecraft:strider_food");
|
||||||
|
public static final ItemCategory STRIDER_TEMPT_ITEMS = get("minecraft:strider_tempt_items");
|
||||||
public static final ItemCategory SWORDS = get("minecraft:swords");
|
public static final ItemCategory SWORDS = get("minecraft:swords");
|
||||||
public static final ItemCategory TALL_FLOWERS = get("minecraft:tall_flowers");
|
public static final ItemCategory TALL_FLOWERS = get("minecraft:tall_flowers");
|
||||||
public static final ItemCategory TERRACOTTA = get("minecraft:terracotta");
|
public static final ItemCategory TERRACOTTA = get("minecraft:terracotta");
|
||||||
public static final ItemCategory TOOLS = get("minecraft:tools");
|
@Deprecated public static final ItemCategory TOOLS = get("minecraft:tools");
|
||||||
public static final ItemCategory TRAPDOORS = get("minecraft:trapdoors");
|
public static final ItemCategory TRAPDOORS = get("minecraft:trapdoors");
|
||||||
public static final ItemCategory TRIM_MATERIALS = get("minecraft:trim_materials");
|
public static final ItemCategory TRIM_MATERIALS = get("minecraft:trim_materials");
|
||||||
public static final ItemCategory TRIM_TEMPLATES = get("minecraft:trim_templates");
|
public static final ItemCategory TRIM_TEMPLATES = get("minecraft:trim_templates");
|
||||||
public static final ItemCategory TRIMMABLE_ARMOR = get("minecraft:trimmable_armor");
|
public static final ItemCategory TRIMMABLE_ARMOR = get("minecraft:trimmable_armor");
|
||||||
|
public static final ItemCategory TURTLE_FOOD = get("minecraft:turtle_food");
|
||||||
public static final ItemCategory VILLAGER_PLANTABLE_SEEDS = get("minecraft:villager_plantable_seeds");
|
public static final ItemCategory VILLAGER_PLANTABLE_SEEDS = get("minecraft:villager_plantable_seeds");
|
||||||
public static final ItemCategory WALLS = get("minecraft:walls");
|
public static final ItemCategory WALLS = get("minecraft:walls");
|
||||||
public static final ItemCategory WARPED_STEMS = get("minecraft:warped_stems");
|
public static final ItemCategory WARPED_STEMS = get("minecraft:warped_stems");
|
||||||
public static final ItemCategory WART_BLOCKS = get("minecraft:wart_blocks");
|
public static final ItemCategory WART_BLOCKS = get("minecraft:wart_blocks");
|
||||||
|
public static final ItemCategory WOLF_FOOD = get("minecraft:wolf_food");
|
||||||
public static final ItemCategory WOODEN_BUTTONS = get("minecraft:wooden_buttons");
|
public static final ItemCategory WOODEN_BUTTONS = get("minecraft:wooden_buttons");
|
||||||
public static final ItemCategory WOODEN_DOORS = get("minecraft:wooden_doors");
|
public static final ItemCategory WOODEN_DOORS = get("minecraft:wooden_doors");
|
||||||
public static final ItemCategory WOODEN_FENCES = get("minecraft:wooden_fences");
|
public static final ItemCategory WOODEN_FENCES = get("minecraft:wooden_fences");
|
||||||
|
@ -42,7 +42,7 @@ public class ItemType implements RegistryItem, Keyed {
|
|||||||
public static final NamespacedRegistry<ItemType> REGISTRY = new NamespacedRegistry<>("item type", true);
|
public static final NamespacedRegistry<ItemType> REGISTRY = new NamespacedRegistry<>("item type", true);
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings({"deprecation", "this-escape"})
|
||||||
private transient final LazyReference<String> name = LazyReference.from(() -> {
|
private transient final LazyReference<String> name = LazyReference.from(() -> {
|
||||||
String name = GuavaUtil.firstNonNull(
|
String name = GuavaUtil.firstNonNull(
|
||||||
WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS)
|
WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS)
|
||||||
@ -51,10 +51,12 @@ public class ItemType implements RegistryItem, Keyed {
|
|||||||
);
|
);
|
||||||
return name.isEmpty() ? getId() : name;
|
return name.isEmpty() ? getId() : name;
|
||||||
});
|
});
|
||||||
|
@SuppressWarnings("this-escape")
|
||||||
private transient final LazyReference<Component> richName = LazyReference.from(() ->
|
private transient final LazyReference<Component> richName = LazyReference.from(() ->
|
||||||
WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS)
|
WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS)
|
||||||
.getRegistries().getItemRegistry().getRichName(this)
|
.getRegistries().getItemRegistry().getRichName(this)
|
||||||
);
|
);
|
||||||
|
@SuppressWarnings("this-escape")
|
||||||
private transient final LazyReference<ItemMaterial> itemMaterial = LazyReference.from(() ->
|
private transient final LazyReference<ItemMaterial> itemMaterial = LazyReference.from(() ->
|
||||||
WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS)
|
WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS)
|
||||||
.getRegistries().getItemRegistry().getMaterial(this)
|
.getRegistries().getItemRegistry().getMaterial(this)
|
||||||
|
@ -105,6 +105,10 @@ public final class ItemTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType ARMOR_STAND = init();
|
public static final ItemType ARMOR_STAND = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final ItemType ARMADILLO_SCUTE = init();
|
||||||
|
@Nullable
|
||||||
|
public static final ItemType ARMADILLO_SPAWN_EGG = init();
|
||||||
|
@Nullable
|
||||||
public static final ItemType ARMS_UP_POTTERY_SHERD = init();
|
public static final ItemType ARMS_UP_POTTERY_SHERD = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType ARROW = init();
|
public static final ItemType ARROW = init();
|
||||||
@ -297,6 +301,10 @@ public final class ItemTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType BLUE_WOOL = init();
|
public static final ItemType BLUE_WOOL = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final ItemType BOGGED_SPAWN_EGG = init();
|
||||||
|
@Nullable
|
||||||
|
public static final ItemType BOLT_ARMOR_TRIM_SMITHING_TEMPLATE = init();
|
||||||
|
@Nullable
|
||||||
public static final ItemType BONE = init();
|
public static final ItemType BONE = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType BONE_BLOCK = init();
|
public static final ItemType BONE_BLOCK = init();
|
||||||
@ -319,6 +327,8 @@ public final class ItemTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType BREAD = init();
|
public static final ItemType BREAD = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final ItemType BREEZE_ROD = init();
|
||||||
|
@Nullable
|
||||||
public static final ItemType BREEZE_SPAWN_EGG = init();
|
public static final ItemType BREEZE_SPAWN_EGG = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType BREWER_POTTERY_SHERD = init();
|
public static final ItemType BREWER_POTTERY_SHERD = init();
|
||||||
@ -971,6 +981,12 @@ public final class ItemTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType FLINT_AND_STEEL = init();
|
public static final ItemType FLINT_AND_STEEL = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final ItemType FLOW_ARMOR_TRIM_SMITHING_TEMPLATE = init();
|
||||||
|
@Nullable
|
||||||
|
public static final ItemType FLOW_BANNER_PATTERN = init();
|
||||||
|
@Nullable
|
||||||
|
public static final ItemType FLOW_POTTERY_SHERD = init();
|
||||||
|
@Nullable
|
||||||
public static final ItemType FLOWER_BANNER_PATTERN = init();
|
public static final ItemType FLOWER_BANNER_PATTERN = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType FLOWER_POT = init();
|
public static final ItemType FLOWER_POT = init();
|
||||||
@ -1132,6 +1148,10 @@ public final class ItemTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType GUNPOWDER = init();
|
public static final ItemType GUNPOWDER = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final ItemType GUSTER_BANNER_PATTERN = init();
|
||||||
|
@Nullable
|
||||||
|
public static final ItemType GUSTER_POTTERY_SHERD = init();
|
||||||
|
@Nullable
|
||||||
public static final ItemType HANGING_ROOTS = init();
|
public static final ItemType HANGING_ROOTS = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType HAY_BLOCK = init();
|
public static final ItemType HAY_BLOCK = init();
|
||||||
@ -1142,6 +1162,8 @@ public final class ItemTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType HEARTBREAK_POTTERY_SHERD = init();
|
public static final ItemType HEARTBREAK_POTTERY_SHERD = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final ItemType HEAVY_CORE = init();
|
||||||
|
@Nullable
|
||||||
public static final ItemType HEAVY_WEIGHTED_PRESSURE_PLATE = init();
|
public static final ItemType HEAVY_WEIGHTED_PRESSURE_PLATE = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType HOGLIN_SPAWN_EGG = init();
|
public static final ItemType HOGLIN_SPAWN_EGG = init();
|
||||||
@ -1404,6 +1426,8 @@ public final class ItemTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType LOOM = init();
|
public static final ItemType LOOM = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final ItemType MACE = init();
|
||||||
|
@Nullable
|
||||||
public static final ItemType MAGENTA_BANNER = init();
|
public static final ItemType MAGENTA_BANNER = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType MAGENTA_BED = init();
|
public static final ItemType MAGENTA_BED = init();
|
||||||
@ -1668,6 +1692,10 @@ public final class ItemTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType OCHRE_FROGLIGHT = init();
|
public static final ItemType OCHRE_FROGLIGHT = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final ItemType OMINOUS_BOTTLE = init();
|
||||||
|
@Nullable
|
||||||
|
public static final ItemType OMINOUS_TRIAL_KEY = init();
|
||||||
|
@Nullable
|
||||||
public static final ItemType ORANGE_BANNER = init();
|
public static final ItemType ORANGE_BANNER = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType ORANGE_BED = init();
|
public static final ItemType ORANGE_BED = init();
|
||||||
@ -2075,6 +2103,8 @@ public final class ItemTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType SCAFFOLDING = init();
|
public static final ItemType SCAFFOLDING = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final ItemType SCRAPE_POTTERY_SHERD = init();
|
||||||
|
@Nullable
|
||||||
public static final ItemType SCULK = init();
|
public static final ItemType SCULK = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType SCULK_CATALYST = init();
|
public static final ItemType SCULK_CATALYST = init();
|
||||||
@ -2085,6 +2115,7 @@ public final class ItemTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType SCULK_VEIN = init();
|
public static final ItemType SCULK_VEIN = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@Deprecated
|
||||||
public static final ItemType SCUTE = init();
|
public static final ItemType SCUTE = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType SEA_LANTERN = init();
|
public static final ItemType SEA_LANTERN = init();
|
||||||
@ -2424,10 +2455,14 @@ public final class ItemTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType TURTLE_HELMET = init();
|
public static final ItemType TURTLE_HELMET = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final ItemType TURTLE_SCUTE = init();
|
||||||
|
@Nullable
|
||||||
public static final ItemType TURTLE_SPAWN_EGG = init();
|
public static final ItemType TURTLE_SPAWN_EGG = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType TWISTING_VINES = init();
|
public static final ItemType TWISTING_VINES = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final ItemType VAULT = init();
|
||||||
|
@Nullable
|
||||||
public static final ItemType VERDANT_FROGLIGHT = init();
|
public static final ItemType VERDANT_FROGLIGHT = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType VEX_ARMOR_TRIM_SMITHING_TEMPLATE = init();
|
public static final ItemType VEX_ARMOR_TRIM_SMITHING_TEMPLATE = init();
|
||||||
@ -2614,6 +2649,8 @@ public final class ItemTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType WILD_ARMOR_TRIM_SMITHING_TEMPLATE = init();
|
public static final ItemType WILD_ARMOR_TRIM_SMITHING_TEMPLATE = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final ItemType WIND_CHARGE = init();
|
||||||
|
@Nullable
|
||||||
public static final ItemType WITCH_SPAWN_EGG = init();
|
public static final ItemType WITCH_SPAWN_EGG = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType WITHER_ROSE = init();
|
public static final ItemType WITHER_ROSE = init();
|
||||||
@ -2624,6 +2661,8 @@ public final class ItemTypes {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType WITHER_SPAWN_EGG = init();
|
public static final ItemType WITHER_SPAWN_EGG = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
|
public static final ItemType WOLF_ARMOR = init();
|
||||||
|
@Nullable
|
||||||
public static final ItemType WOLF_SPAWN_EGG = init();
|
public static final ItemType WOLF_SPAWN_EGG = init();
|
||||||
@Nullable
|
@Nullable
|
||||||
public static final ItemType WOODEN_AXE = init();
|
public static final ItemType WOODEN_AXE = init();
|
||||||
|
@ -28,7 +28,7 @@ dependencies {
|
|||||||
})
|
})
|
||||||
api("org.apache.logging.log4j:log4j-api")
|
api("org.apache.logging.log4j:log4j-api")
|
||||||
api("org.bstats:bstats-sponge:1.7")
|
api("org.bstats:bstats-sponge:1.7")
|
||||||
testImplementation("org.mockito:mockito-core:5.11.0")
|
testImplementation("org.mockito:mockito-core:5.12.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
|
Loading…
Reference in New Issue
Block a user