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

Merge branch 'main' into v3

Dieser Commit ist enthalten in:
dordsor21 2024-03-15 11:24:23 +01:00
Commit 0264ba3f53
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 6F2096C3F39EF392
57 geänderte Dateien mit 646 neuen und 259 gelöschten Zeilen

Datei anzeigen

@ -342,7 +342,7 @@ ij_editorconfig_space_before_colon = false
ij_editorconfig_space_before_comma = false ij_editorconfig_space_before_comma = false
ij_editorconfig_spaces_around_assignment_operators = true ij_editorconfig_spaces_around_assignment_operators = true
[{*.ant, *.fxml, *.jhm, *.jnlp, *.jrxml, *.pom, *.rng, *.tld, *.wsdl, *.xml, *.xsd, *.xsl, *.xslt, *.xul}] [{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.pom,*.rng,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul}]
ij_xml_align_attributes = true ij_xml_align_attributes = true
ij_xml_align_text = false ij_xml_align_text = false
ij_xml_attribute_wrap = normal ij_xml_attribute_wrap = normal
@ -360,7 +360,7 @@ ij_xml_space_around_equals_in_attribute = false
ij_xml_space_inside_empty_tag = false ij_xml_space_inside_empty_tag = false
ij_xml_text_wrap = normal ij_xml_text_wrap = normal
[{*.ats, *.ts}] [{*.ats,*.ts}]
ij_continuation_indent_size = 4 ij_continuation_indent_size = 4
ij_typescript_align_imports = false ij_typescript_align_imports = false
ij_typescript_align_multiline_array_initializer_expression = false ij_typescript_align_multiline_array_initializer_expression = false
@ -528,7 +528,7 @@ ij_typescript_while_brace_force = never
ij_typescript_while_on_new_line = false ij_typescript_while_on_new_line = false
ij_typescript_wrap_comments = false ij_typescript_wrap_comments = false
[{*.bash, *.sh, *.zsh}] [{*.bash,*.sh,*.zsh}]
indent_size = 2 indent_size = 2
tab_width = 2 tab_width = 2
ij_shell_binary_ops_start_line = false ij_shell_binary_ops_start_line = false
@ -537,7 +537,7 @@ ij_shell_minify_program = false
ij_shell_redirect_followed_by_space = false ij_shell_redirect_followed_by_space = false
ij_shell_switch_cases_indented = false ij_shell_switch_cases_indented = false
[{*.cjs, *.js}] [{*.cjs,*.js}]
ij_continuation_indent_size = 4 ij_continuation_indent_size = 4
ij_javascript_align_imports = false ij_javascript_align_imports = false
ij_javascript_align_multiline_array_initializer_expression = false ij_javascript_align_multiline_array_initializer_expression = false
@ -702,10 +702,10 @@ ij_javascript_while_brace_force = never
ij_javascript_while_on_new_line = false ij_javascript_while_on_new_line = false
ij_javascript_wrap_comments = false ij_javascript_wrap_comments = false
[{*.ft, *.vm, *.vsl}] [{*.ft,*.vm,*.vsl}]
ij_vtl_keep_indents_on_empty_lines = false ij_vtl_keep_indents_on_empty_lines = false
[{*.gant, *.gradle, *.groovy, *.gy}] [{*.gant,*.gradle,*.groovy,*.gy}]
ij_groovy_align_group_field_declarations = false ij_groovy_align_group_field_declarations = false
ij_groovy_align_multiline_array_initializer_expression = false ij_groovy_align_multiline_array_initializer_expression = false
ij_groovy_align_multiline_assignment = false ij_groovy_align_multiline_assignment = false
@ -884,7 +884,7 @@ ij_groovy_while_brace_force = never
ij_groovy_while_on_new_line = false ij_groovy_while_on_new_line = false
ij_groovy_wrap_long_lines = false ij_groovy_wrap_long_lines = false
[{*.gradle.kts, *.kt, *.kts, *.main.kts}] [{*.gradle.kts,*.kt,*.kts,*.main.kts}]
ij_kotlin_align_in_columns_case_branch = false ij_kotlin_align_in_columns_case_branch = false
ij_kotlin_align_multiline_binary_operation = false ij_kotlin_align_multiline_binary_operation = false
ij_kotlin_align_multiline_extends_list = false ij_kotlin_align_multiline_extends_list = false
@ -963,7 +963,7 @@ ij_kotlin_wrap_elvis_expressions = 1
ij_kotlin_wrap_expression_body_functions = 0 ij_kotlin_wrap_expression_body_functions = 0
ij_kotlin_wrap_first_method_in_call_chain = false ij_kotlin_wrap_first_method_in_call_chain = false
[{*.har, *.jsb2, *.jsb3, *.json, .babelrc, .eslintrc, .stylelintrc, bowerrc, jest.config, mcmod.info}] [{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,jest.config,mcmod.info}]
indent_size = 2 indent_size = 2
ij_json_keep_blank_lines_in_code = 0 ij_json_keep_blank_lines_in_code = 0
ij_json_keep_indents_on_empty_lines = false ij_json_keep_indents_on_empty_lines = false
@ -976,7 +976,7 @@ ij_json_spaces_within_braces = false
ij_json_spaces_within_brackets = false ij_json_spaces_within_brackets = false
ij_json_wrap_long_lines = false ij_json_wrap_long_lines = false
[{*.htm, *.html, *.sht, *.shtm, *.shtml}] [{*.htm,*.html,*.sht,*.shtm,*.shtml}]
ij_html_add_new_line_before_tags = body, div, p, form, h1, h2, h3 ij_html_add_new_line_before_tags = body, div, p, form, h1, h2, h3
ij_html_align_attributes = true ij_html_align_attributes = true
ij_html_align_text = false ij_html_align_text = false
@ -1004,7 +1004,7 @@ ij_html_space_inside_empty_tag = false
ij_html_text_wrap = normal ij_html_text_wrap = normal
ij_html_uniform_ident = false ij_html_uniform_ident = false
[{*.yaml, *.yml}] [{*.yaml,*.yml}]
indent_size = 2 indent_size = 2
ij_yaml_keep_indents_on_empty_lines = false ij_yaml_keep_indents_on_empty_lines = false
ij_yaml_keep_line_breaks = true ij_yaml_keep_line_breaks = true

47
.github/renovate.json vendored
Datei anzeigen

@ -1,18 +1,18 @@
{ {
"$schema": "https://docs.renovatebot.com/renovate-schema.json", "$schema" : "https://docs.renovatebot.com/renovate-schema.json",
"extends": [ "extends" : [
"config:base", "config:recommended",
":semanticCommitsDisabled" ":semanticCommitsDisabled"
], ],
"automerge": true, "automerge" : true,
"ignoreDeps": [ "ignoreDeps" : [
"guava", "guava",
"com.google.guava:guava", "com.google.guava:guava",
"rhino-runtime", "rhino-runtime",
"org.antlr", "org.antlr",
"antlr4-runtime", "antlr4-runtime",
"fastutil", "fastutil",
"it.unimi.dsi:fastutil", "it.unimi.dsi:fastutil",
"auto-value-annotations", "auto-value-annotations",
"auto-value", "auto-value",
"com.google.code.gson:gson", "com.google.code.gson:gson",
@ -29,7 +29,34 @@
"org.spongepowered:spongeapi", "org.spongepowered:spongeapi",
"org.yaml:snakeyaml" "org.yaml:snakeyaml"
], ],
"labels": ["Renovate"], "labels" : [
"rebaseWhen": "conflicted", "Renovate"
"schedule": ["on the first day of the month"] ],
"rebaseWhen" : "conflicted",
"customManagers" : [
{
"customType" : "regex",
"datasourceTemplate" : "custom.paperweight-userdev",
"fileMatch" : "^worldedit-bukkit\\/adapters\\/adapter-\\d+_\\d+(_\\d+)?\\/build\\.gradle\\.kts$",
"matchStrings" : [
"url=(?<registryUrl>.*)\\s",
"paperDevBundle\\(\"(?<currentValue>.*?)\"\\)\\s"
],
"matchStringsStrategy": "combination",
"depNameTemplate" : "paperweight-userdev",
"extractVersionTemplate" : "(?<version>\\d+\\.\\d+\\.?\\d*-R0\\.1-\\d+\\.\\d+-\\d+)"
}
],
"customDatasources" : {
"paperweight-userdev": {
"defaultRegistryUrlTemplate": "",
"format": "html"
}
},
"packageRules" : [
{
"matchDatasources" : ["custom.paperweight-userdev"],
"versioning": "regex:^(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)?-R0\\.1-\\d+\\d+\\.\\d+-(?<build>\\d+)$"
}
]
} }

Datei anzeigen

@ -11,7 +11,7 @@ jobs:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Validate Gradle Wrapper - name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1 uses: gradle/wrapper-validation-action@v2
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:

Datei anzeigen

@ -11,7 +11,7 @@ jobs:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Validate Gradle Wrapper - name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1 uses: gradle/wrapper-validation-action@v2
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:

Datei anzeigen

@ -27,10 +27,10 @@ jobs:
cache: gradle cache: gradle
java-version: 17 java-version: 17
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v3
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v2 uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2 uses: github/codeql-action/analyze@v3

Datei anzeigen

@ -12,6 +12,6 @@ jobs:
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }} if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: release-drafter/release-drafter@v5 - uses: release-drafter/release-drafter@v6
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Datei anzeigen

@ -9,7 +9,7 @@ jobs:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Validate Gradle Wrapper - name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1 uses: gradle/wrapper-validation-action@v2
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:

Datei anzeigen

@ -7,7 +7,7 @@ import xyz.jpenilla.runpaper.task.RunServer
plugins { plugins {
id("io.github.gradle-nexus.publish-plugin") version "1.3.0" id("io.github.gradle-nexus.publish-plugin") version "1.3.0"
id("xyz.jpenilla.run-paper") version "2.2.2" id("xyz.jpenilla.run-paper") version "2.2.3"
} }
if (!File("$rootDir/.git").exists()) { if (!File("$rootDir/.git").exists()) {
@ -34,7 +34,7 @@ logger.lifecycle("""
******************************************* *******************************************
""") """)
var rootVersion by extra("2.8.4") var rootVersion by extra("2.9.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("")

Datei anzeigen

@ -22,9 +22,9 @@ val properties = Properties().also { props ->
dependencies { dependencies {
implementation(gradleApi()) implementation(gradleApi())
implementation("org.ajoberstar.grgit:grgit-gradle:5.2.1") 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.10") implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.5.11")
} }
kotlin { kotlin {

Datei anzeigen

@ -1,6 +1,6 @@
[versions] [versions]
# Minecraft expectations # Minecraft expectations
paper = "1.20.2-R0.1-SNAPSHOT" paper = "1.20.4-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"
@ -11,19 +11,19 @@ snakeyaml = "2.0"
dummypermscompat = "1.10" dummypermscompat = "1.10"
worldguard-bukkit = "7.0.9" worldguard-bukkit = "7.0.9"
mapmanager = "1.8.0-SNAPSHOT" mapmanager = "1.8.0-SNAPSHOT"
griefprevention = "16.18.1" 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.0.8" towny = "0.100.1.20"
plotsquared = "7.2.0" plotsquared = "7.3.6"
# 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.14.0" adventure = "4.16.0"
adventure-bukkit = "4.3.1" adventure-bukkit = "4.3.2"
checkerqual = "3.41.0" checkerqual = "3.42.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"
@ -43,10 +43,10 @@ serverlib = "2.3.4"
## Internal ## Internal
text-adapter = "3.0.6" text-adapter = "3.0.6"
text = "3.0.4" text = "3.0.4"
piston = "0.5.7" piston = "0.5.8"
# Tests # Tests
mockito = "5.8.0" mockito = "5.11.0"
# Gradle plugins # Gradle plugins
pluginyml = "0.6.0" pluginyml = "0.6.0"

Datei anzeigen

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

20
gradlew.bat vendored
Datei anzeigen

@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail

Datei anzeigen

@ -21,6 +21,7 @@ configurations.all {
dependencies { dependencies {
// url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.17.1-R0.1-SNAPSHOT
the<PaperweightUserDependenciesExtension>().paperDevBundle("1.17.1-R0.1-20220414.034903-210") the<PaperweightUserDependenciesExtension>().paperDevBundle("1.17.1-R0.1-20220414.034903-210")
compileOnly(libs.paperlib) compileOnly(libs.paperlib)
} }

Datei anzeigen

@ -148,6 +148,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked.");
} }
this.createCopy = createCopy; this.createCopy = createCopy;
// Increment regardless of whether copy will be created or not to return null from getCopy()
return ++this.copyKey; return ++this.copyKey;
} }

Datei anzeigen

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

Datei anzeigen

@ -153,6 +153,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked.");
} }
this.createCopy = createCopy; this.createCopy = createCopy;
// Increment regardless of whether copy will be created or not to return null from getCopy()
return ++this.copyKey; return ++this.copyKey;
} }

Datei anzeigen

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

Datei anzeigen

@ -156,6 +156,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked.");
} }
this.createCopy = createCopy; this.createCopy = createCopy;
// Increment regardless of whether copy will be created or not to return null from getCopy()
return ++this.copyKey; return ++this.copyKey;
} }

Datei anzeigen

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

Datei anzeigen

@ -156,6 +156,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked.");
} }
this.createCopy = createCopy; this.createCopy = createCopy;
// Increment regardless of whether copy will be created or not to return null from getCopy()
return ++this.copyKey; return ++this.copyKey;
} }

Datei anzeigen

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

Datei anzeigen

@ -135,6 +135,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked.");
} }
this.createCopy = createCopy; this.createCopy = createCopy;
// Increment regardless of whether copy will be created or not to return null from getCopy()
return ++this.copyKey; return ++this.copyKey;
} }

Datei anzeigen

@ -11,7 +11,7 @@ repositories {
} }
dependencies { dependencies {
// https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/ // 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-20231207.202833-1") the<PaperweightUserDependenciesExtension>().paperDevBundle("1.20.4-R0.1-20240106.182028-62")
compileOnly(libs.paperlib) compileOnly(libs.paperlib)
} }

Datei anzeigen

@ -135,6 +135,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked.");
} }
this.createCopy = createCopy; this.createCopy = createCopy;
// Increment regardless of whether copy will be created or not to return null from getCopy()
return ++this.copyKey; return ++this.copyKey;
} }

Datei anzeigen

@ -141,20 +141,15 @@ tasks.named<Jar>("jar") {
addJarManifest(WorldEditKind.Plugin, includeClasspath = true) addJarManifest(WorldEditKind.Plugin, includeClasspath = true)
tasks.named<ShadowJar>("shadowJar") { tasks.named<ShadowJar>("shadowJar") {
dependsOn(project.project(":worldedit-bukkit:adapters").subprojects.map { it.tasks.named("assemble") }) configurations.add(adapters)
from(Callable {
adapters.resolve()
.map { f ->
zipTree(f).matching {
exclude("META-INF/")
}
}
})
archiveFileName.set("${rootProject.name}-Bukkit-${project.version}.${archiveExtension.getOrElse("jar")}") archiveFileName.set("${rootProject.name}-Bukkit-${project.version}.${archiveExtension.getOrElse("jar")}")
dependencies { dependencies {
// In tandem with not bundling log4j, we shouldn't relocate base package here. // In tandem with not bundling log4j, we shouldn't relocate base package here.
// relocate("org.apache.logging", "com.sk89q.worldedit.log4j") // relocate("org.apache.logging", "com.sk89q.worldedit.log4j")
relocate("org.antlr.v4", "com.sk89q.worldedit.antlr4") relocate("org.antlr.v4", "com.sk89q.worldedit.antlr4")
exclude(dependency("$group:$name"))
include(dependency(":worldedit-core")) include(dependency(":worldedit-core"))
include(dependency(":worldedit-libs:bukkit")) include(dependency(":worldedit-libs:bukkit"))
// Purposefully not included, we assume (even though no API exposes it) that Log4J will be present at runtime // Purposefully not included, we assume (even though no API exposes it) that Log4J will be present at runtime
@ -183,7 +178,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.14.0")) include(dependency("net.kyori:adventure-nbt:4.16.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"))
@ -192,6 +187,15 @@ tasks.named<ShadowJar>("shadowJar") {
include(dependency("org.anarres:parallelgzip:1.0.5")) include(dependency("org.anarres:parallelgzip:1.0.5"))
} }
} }
project.project(":worldedit-bukkit:adapters").subprojects.forEach {
dependencies {
include(dependency("${it.group}:${it.name}"))
}
minimize {
exclude(dependency("${it.group}:${it.name}"))
}
}
} }
tasks.named("assemble").configure { tasks.named("assemble").configure {

Datei anzeigen

@ -163,13 +163,22 @@ public class WorldGuardFeature extends BukkitMaskManager implements Listener {
final Location location = player.getLocation(); final Location location = player.getLocation();
final Set<ProtectedRegion> regions = this.getRegions(localplayer, location, isWhitelist); final Set<ProtectedRegion> regions = this.getRegions(localplayer, location, isWhitelist);
if (!regions.isEmpty()) { if (!regions.isEmpty()) {
RegionManager manager = WorldGuard
.getInstance()
.getPlatform()
.getRegionContainer()
.get(BukkitAdapter.adapt(location.getWorld()));
if (manager == null) {
return null;
}
Set<Region> result = new HashSet<>(); Set<Region> result = new HashSet<>();
for (ProtectedRegion myRegion : regions) { for (ProtectedRegion myRegion : regions) {
if (myRegion.getId().equals("__global__")) { if (myRegion.getId().equals("__global__")) {
return new FaweMask(RegionWrapper.GLOBAL()) { return new FaweMask(RegionWrapper.GLOBAL()) {
@Override @Override
public boolean isValid(com.sk89q.worldedit.entity.Player player, MaskType type) { public boolean isValid(com.sk89q.worldedit.entity.Player player, MaskType type) {
return isAllowed(worldguard.wrapPlayer(BukkitAdapter.adapt(player)), myRegion); return manager.hasRegion(myRegion.getId())
&& isAllowed(worldguard.wrapPlayer(BukkitAdapter.adapt(player)), myRegion);
} }
}; };
} else { } else {
@ -185,7 +194,7 @@ public class WorldGuardFeature extends BukkitMaskManager implements Listener {
public boolean isValid(com.sk89q.worldedit.entity.Player player, MaskType type) { public boolean isValid(com.sk89q.worldedit.entity.Player player, MaskType type) {
final LocalPlayer localplayer = worldguard.wrapPlayer(BukkitAdapter.adapt(player)); final LocalPlayer localplayer = worldguard.wrapPlayer(BukkitAdapter.adapt(player));
for (ProtectedRegion myRegion : regions) { for (ProtectedRegion myRegion : regions) {
if (!isAllowed(localplayer, myRegion)) { if (!manager.hasRegion(myRegion.getId()) || !isAllowed(localplayer, myRegion)) {
return false; return false;
} }
} }

Datei anzeigen

@ -16,6 +16,7 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.function.FlatRegionFunction; import com.sk89q.worldedit.function.FlatRegionFunction;
@ -217,7 +218,6 @@ public class FaweDelegateRegionManager {
) { ) {
TaskManager.taskManager().async(() -> { TaskManager.taskManager().async(() -> {
synchronized (FaweDelegateRegionManager.class) { synchronized (FaweDelegateRegionManager.class) {
//todo because of the following code this should probably be in the Bukkit module
World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorldName())); World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorldName()));
World pos3World = BukkitAdapter.adapt(getWorld(swapPos.getWorldName())); World pos3World = BukkitAdapter.adapt(getWorld(swapPos.getWorldName()));
EditSession sessionA = WorldEdit.getInstance().newEditSessionBuilder().world(pos1World) EditSession sessionA = WorldEdit.getInstance().newEditSessionBuilder().world(pos1World)
@ -236,14 +236,16 @@ public class FaweDelegateRegionManager {
CuboidRegion regionB = new CuboidRegion( CuboidRegion regionB = new CuboidRegion(
pos3World, pos3World,
swapPos.getBlockVector3(), swapPos.getBlockVector3(),
swapPos.getBlockVector3().add(pos2.getBlockVector3()).subtract(pos1.getBlockVector3()) swapPos.getBlockVector3().add(pos2.getBlockVector3().subtract(pos1.getBlockVector3())).withY(pos2.getY())
); );
Clipboard clipA = Clipboard.create(regionA, UUID.randomUUID()); Clipboard clipA = new BlockArrayClipboard(regionA, UUID.randomUUID());
Clipboard clipB = Clipboard.create(regionB, UUID.randomUUID()); Clipboard clipB = new BlockArrayClipboard(regionB, UUID.randomUUID());
ForwardExtentCopy copyA = new ForwardExtentCopy(sessionA, regionA, clipA, clipA.getMinimumPoint()); ForwardExtentCopy copyA = new ForwardExtentCopy(sessionA, regionA, clipA, clipA.getMinimumPoint());
ForwardExtentCopy copyB = new ForwardExtentCopy(sessionB, regionB, clipB, clipB.getMinimumPoint()); ForwardExtentCopy copyB = new ForwardExtentCopy(sessionB, regionB, clipB, clipB.getMinimumPoint());
copyA.setCopyingBiomes(true); copyA.setCopyingBiomes(true);
copyB.setCopyingBiomes(true); copyB.setCopyingBiomes(true);
copyA.setCopyingEntities(true);
copyB.setCopyingEntities(true);
try { try {
Operations.completeLegacy(copyA); Operations.completeLegacy(copyA);
Operations.completeLegacy(copyB); Operations.completeLegacy(copyB);
@ -257,17 +259,16 @@ public class FaweDelegateRegionManager {
sessionA.close(); sessionA.close();
sessionB.close(); sessionB.close();
} }
FaweAPI.fixLighting(pos1World, new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()), null, FaweAPI.fixLighting(
pos1World,
regionA,
null,
RelightMode.valueOf(com.fastasyncworldedit.core.configuration.Settings.settings().LIGHTING.MODE) RelightMode.valueOf(com.fastasyncworldedit.core.configuration.Settings.settings().LIGHTING.MODE)
); );
FaweAPI.fixLighting(pos1World, new CuboidRegion( FaweAPI.fixLighting(
swapPos.getBlockVector3(), pos1World,
BlockVector3.at( regionB,
swapPos.getX() + pos2.getX() - pos1.getX(), null,
0,
swapPos.getZ() + pos2.getZ() - pos1.getZ()
)
), null,
RelightMode.valueOf(com.fastasyncworldedit.core.configuration.Settings.settings().LIGHTING.MODE) RelightMode.valueOf(com.fastasyncworldedit.core.configuration.Settings.settings().LIGHTING.MODE)
); );
if (whenDone != null) { if (whenDone != null) {

Datei anzeigen

@ -245,6 +245,11 @@ public class TestOfflinePermissible implements OfflinePlayer, Permissible {
throw new UnsupportedOperationException("Not supported yet."); throw new UnsupportedOperationException("Not supported yet.");
} }
@Override
public @Nullable Location getRespawnLocation() {
return null;
}
@Override @Override
public void incrementStatistic(@Nonnull Statistic statistic) throws IllegalArgumentException { public void incrementStatistic(@Nonnull Statistic statistic) throws IllegalArgumentException {
@ -365,4 +370,9 @@ public class TestOfflinePermissible implements OfflinePlayer, Permissible {
return null; return null;
} }
@Override
public @Nullable Location getLocation() {
return null;
}
} }

Datei anzeigen

@ -612,12 +612,38 @@ public enum FaweCache implements Trimable {
/* /*
Thread stuff Thread stuff
*/ */
/**
* Create a new blocking executor with default name and FaweCache logger
*
* @return new blocking executor
*/
public ThreadPoolExecutor newBlockingExecutor() { public ThreadPoolExecutor newBlockingExecutor() {
return newBlockingExecutor("FAWE Blocking Executor - %d");
}
/**
* Create a new blocking executor with specified name and FaweCache logger
*
* @return new blocking executor
* @since 2.9.0
*/
public ThreadPoolExecutor newBlockingExecutor(String name) {
return newBlockingExecutor(name, LOGGER);
}
/**
* Create a new blocking executor with specified name and logger
*
* @return new blocking executor
* @since 2.9.0
*/
public ThreadPoolExecutor newBlockingExecutor(String name, Logger logger) {
int nThreads = Settings.settings().QUEUE.PARALLEL_THREADS; int nThreads = Settings.settings().QUEUE.PARALLEL_THREADS;
ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(nThreads, true); ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(nThreads, true);
return new ThreadPoolExecutor(nThreads, nThreads, return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS, queue, 0L, TimeUnit.MILLISECONDS, queue,
new ThreadFactoryBuilder().setNameFormat("FAWE Blocking Executor - %d").build(), new ThreadFactoryBuilder().setNameFormat(name).build(),
new ThreadPoolExecutor.CallerRunsPolicy() new ThreadPoolExecutor.CallerRunsPolicy()
) { ) {
@ -652,10 +678,10 @@ public enum FaweCache implements Trimable {
int hash = throwable.getMessage() != null ? throwable.getMessage().hashCode() : 0; int hash = throwable.getMessage() != null ? throwable.getMessage().hashCode() : 0;
if (hash != lastException) { if (hash != lastException) {
lastException = hash; lastException = hash;
LOGGER.catching(throwable); logger.catching(throwable);
count = 0; count = 0;
} else if (count < Settings.settings().QUEUE.PARALLEL_THREADS) { } else if (count < Settings.settings().QUEUE.PARALLEL_THREADS) {
LOGGER.warn(throwable.getMessage()); logger.warn(throwable.getMessage());
count++; count++;
} }
} }
@ -665,10 +691,10 @@ public enum FaweCache implements Trimable {
private void handleFaweException(FaweException e) { private void handleFaweException(FaweException e) {
FaweException.Type type = e.getType(); FaweException.Type type = e.getType();
if (e.getType() == FaweException.Type.OTHER) { if (e.getType() == FaweException.Type.OTHER) {
LOGGER.catching(e); logger.catching(e);
} else if (!faweExceptionReasonsUsed[type.ordinal()]) { } else if (!faweExceptionReasonsUsed[type.ordinal()]) {
faweExceptionReasonsUsed[type.ordinal()] = true; faweExceptionReasonsUsed[type.ordinal()] = true;
LOGGER.warn("FaweException: " + e.getMessage()); logger.warn("FaweException: " + e.getMessage());
} }
} }
}; };

Datei anzeigen

@ -67,11 +67,11 @@ public class ErodeBrush implements Brush {
final int by = target.getBlockY(); final int by = target.getBlockY();
final int bz = target.getBlockZ(); final int bz = target.getBlockZ();
for (int x = -brushSize, relx = 0; x <= brushSize; x++, relx++) { for (int x = -brushSize, relx = 0; x <= brushSize && relx < buffer1.getWidth(); x++, relx++) {
int x0 = x + bx; int x0 = x + bx;
for (int y = -brushSize, rely = 0; y <= brushSize; y++, rely++) { for (int y = -brushSize, rely = 0; y <= brushSize && rely < buffer1.getHeight(); y++, rely++) {
int y0 = y + by; int y0 = y + by;
for (int z = -brushSize, relz = 0; z <= brushSize; z++, relz++) { for (int z = -brushSize, relz = 0; z <= brushSize && relz < buffer1.getLength(); z++, relz++) {
int z0 = z + bz; int z0 = z + bz;
BlockState state = es.getBlock(x0, y0, z0); BlockState state = es.getBlock(x0, y0, z0);
buffer1.setBlock(relx, rely, relz, state); buffer1.setBlock(relx, rely, relz, state);
@ -115,11 +115,11 @@ public class ErodeBrush implements Brush {
Clipboard current, Clipboard target Clipboard current, Clipboard target
) { ) {
int[] frequency = null; int[] frequency = null;
for (int x = -brushSize, relx = 0; x <= brushSize; x++, relx++) { for (int x = -brushSize, relx = 0; x <= brushSize && relx < target.getWidth(); x++, relx++) {
int x2 = x * x; int x2 = x * x;
for (int z = -brushSize, relz = 0; z <= brushSize; z++, relz++) { for (int z = -brushSize, relz = 0; z <= brushSize && relz < target.getLength(); z++, relz++) {
int x2y2 = x2 + z * z; int x2y2 = x2 + z * z;
for (int y = -brushSize, rely = 0; y <= brushSize; y++, rely++) { for (int y = -brushSize, rely = 0; y <= brushSize && rely < target.getHeight(); y++, rely++) {
int cube = x2y2 + y * y; int cube = x2y2 + y * y;
target.setBlock(relx, rely, relz, current.getBlock(relx, rely, relz)); target.setBlock(relx, rely, relz, current.getBlock(relx, rely, relz));
if (cube >= brushSizeSquared) { if (cube >= brushSizeSquared) {
@ -166,11 +166,11 @@ public class ErodeBrush implements Brush {
Clipboard current, Clipboard target Clipboard current, Clipboard target
) { ) {
int[] frequency = null; int[] frequency = null;
for (int x = -brushSize, relx = 0; x <= brushSize; x++, relx++) { for (int x = -brushSize, relx = 0; x <= brushSize && relx < target.getWidth(); x++, relx++) {
int x2 = x * x; int x2 = x * x;
for (int z = -brushSize, relz = 0; z <= brushSize; z++, relz++) { for (int z = -brushSize, relz = 0; z <= brushSize && relz < target.getLength(); z++, relz++) {
int x2y2 = x2 + z * z; int x2y2 = x2 + z * z;
for (int y = -brushSize, rely = 0; y <= brushSize; y++, rely++) { for (int y = -brushSize, rely = 0; y <= brushSize && rely < target.getHeight(); y++, rely++) {
int cube = x2y2 + y * y; int cube = x2y2 + y * y;
target.setBlock(relx, rely, relz, current.getBlock(relx, rely, relz)); target.setBlock(relx, rely, relz, current.getBlock(relx, rely, relz));
if (cube >= brushSizeSquared) { if (cube >= brushSizeSquared) {

Datei anzeigen

@ -721,6 +721,13 @@ public class Settings extends Config {
" - Requires clipboard.use-disk to be enabled" " - Requires clipboard.use-disk to be enabled"
}) })
public boolean SAVE_CLIPBOARD_NBT_TO_DISK = true; public boolean SAVE_CLIPBOARD_NBT_TO_DISK = true;
@Comment({
"Apply a file lock on the clipboard file (only relevant if clipboad.on-disk is enabled)",
" - Prevents other processes using the file whilst in use by FAWE",
" - This extends to other servers, useful if you have multiple servers using a unified clipboard folder",
" - May run into issues where a file lock is not correctly lifted"
})
public boolean LOCK_CLIPBOARD_FILE = false;
} }

Datei anzeigen

@ -159,18 +159,23 @@ public class RollbackDatabase extends AsyncNotifyQueue {
Future<Integer> future = call(() -> { Future<Integer> future = call(() -> {
try { try {
int count = 0; int count = 0;
String stmtStr; String stmtStr = """
SELECT * FROM `%sedits`
WHERE `time` > ?
AND `x2` >= ?
AND `x1` <= ?
AND `z2` >= ?
AND `z1` <= ?
AND `y2` >= ?
AND `y1` <= ?
""";
if (uuid != null) {
stmtStr += "\n AND `player`= ?";
}
if (ascending) { if (ascending) {
if (uuid == null) { stmtStr += "\n ORDER BY `time` ASC, `id` ASC";
stmtStr = "SELECT * FROM`%sedits` WHERE `time`>? AND `x2`>=? AND `x1`<=? AND `z2`>=? AND `z1`<=? AND " +
"`y2`>=? AND `y1`<=? ORDER BY `time` , `id`";
} else {
stmtStr = "SELECT * FROM`%sedits` WHERE `time`>? AND `x2`>=? AND `x1`<=? AND `z2`>=? AND `z1`<=? AND " +
"`y2`>=? AND `y1`<=? AND `player`=? ORDER BY `time` ASC, `id` ASC";
}
} else { } else {
stmtStr = "SELECT * FROM`%sedits` WHERE `time`>? AND `x2`>=? AND `x1`<=? AND `z2`>=? AND `z1`<=? AND " + stmtStr += "\n ORDER BY `time` DESC, `id` DESC";
"`y2`>=? AND `y1`<=? AND `player`=? ORDER BY `time` DESC, `id` DESC";
} }
try (PreparedStatement stmt = connection.prepareStatement(stmtStr.formatted(this.prefix))) { try (PreparedStatement stmt = connection.prepareStatement(stmtStr.formatted(this.prefix))) {
stmt.setInt(1, (int) (minTime / 1000)); stmt.setInt(1, (int) (minTime / 1000));

Datei anzeigen

@ -6,12 +6,11 @@ import com.fastasyncworldedit.core.queue.IChunkGet;
import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IChunkSet;
import com.fastasyncworldedit.core.regions.RegionWrapper; import com.fastasyncworldedit.core.regions.RegionWrapper;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
public class HeightBoundExtent extends FaweRegionExtent { public class HeightBoundExtent extends FaweRegionExtent {
@ -50,7 +49,8 @@ public class HeightBoundExtent extends FaweRegionExtent {
@Override @Override
public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) { public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) {
if (trimY(set, min, max, true) | trimNBT(set, this::contains)) { BlockVector3 chunkPos = chunk.getChunkBlockCoord().withY(0);
if (trimY(set, min, max, true) | trimNBT(set, this::contains, pos -> this.contains(pos.add(chunkPos)))) {
return set; return set;
} }
return null; return null;

Datei anzeigen

@ -305,22 +305,24 @@ public class DiskOptimizedClipboard extends LinearClipboard {
private void init() throws IOException { private void init() throws IOException {
if (this.fileChannel == null) { if (this.fileChannel == null) {
this.fileChannel = braf.getChannel(); this.fileChannel = braf.getChannel();
try { if (Settings.settings().CLIPBOARD.LOCK_CLIPBOARD_FILE) {
FileLock lock = this.fileChannel.lock(); try {
LOCK_HOLDER_CACHE.put(file.getName(), new LockHolder(lock)); FileLock lock = this.fileChannel.lock();
} catch (OverlappingFileLockException e) { LOCK_HOLDER_CACHE.put(file.getName(), new LockHolder(lock));
LockHolder existing = LOCK_HOLDER_CACHE.get(file.getName()); } catch (OverlappingFileLockException e) {
if (existing != null) { LockHolder existing = LOCK_HOLDER_CACHE.get(file.getName());
long ms = System.currentTimeMillis() - existing.lockHeldSince; if (existing != null) {
LOGGER.error( long ms = System.currentTimeMillis() - existing.lockHeldSince;
"Cannot lock clipboard file {} acquired by thread {}, {}ms ago", LOGGER.error(
file.getName(), "Cannot lock clipboard file {} acquired by thread {}, {}ms ago",
existing.thread, file.getName(),
ms existing.thread,
); ms
);
}
// Rethrow to prevent clipboard access
throw e;
} }
// Rethrow to prevent clipboard access
throw e;
} }
this.byteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, braf.length()); this.byteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, braf.length());
} }

Datei anzeigen

@ -155,7 +155,9 @@ public interface IBatchProcessor {
* Utility method to trim entity and blocks with a provided contains function. * Utility method to trim entity and blocks with a provided contains function.
* *
* @return false if chunk is empty of NBT * @return false if chunk is empty of NBT
* @deprecated tiles are stored in chunk-normalised coordinate space and thus cannot use the same function as entities
*/ */
@Deprecated(forRemoval = true, since = "2.8.4")
default boolean trimNBT(IChunkSet set, Function<BlockVector3, Boolean> contains) { default boolean trimNBT(IChunkSet set, Function<BlockVector3, Boolean> contains) {
Set<CompoundTag> ents = set.getEntities(); Set<CompoundTag> ents = set.getEntities();
if (!ents.isEmpty()) { if (!ents.isEmpty()) {
@ -169,6 +171,26 @@ public interface IBatchProcessor {
return !tiles.isEmpty() || !ents.isEmpty(); return !tiles.isEmpty() || !ents.isEmpty();
} }
/**
* Utility method to trim entity and blocks with a provided contains function.
*
* @return false if chunk is empty of NBT
* @since 2.8.4
*/
default boolean trimNBT(
IChunkSet set, Function<BlockVector3, Boolean> containsEntity, Function<BlockVector3, Boolean> containsTile
) {
Set<CompoundTag> ents = set.getEntities();
if (!ents.isEmpty()) {
ents.removeIf(ent -> !containsEntity.apply(ent.getEntityPosition().toBlockPoint()));
}
Map<BlockVector3, CompoundTag> tiles = set.getTiles();
if (!tiles.isEmpty()) {
tiles.entrySet().removeIf(blockVector3CompoundTagEntry -> !containsTile.apply(blockVector3CompoundTagEntry.getKey()));
}
return !tiles.isEmpty() || !ents.isEmpty();
}
/** /**
* Join two processors and return the result. * Join two processors and return the result.
*/ */

Datei anzeigen

@ -1,6 +1,7 @@
package com.fastasyncworldedit.core.queue; package com.fastasyncworldedit.core.queue;
import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock; import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -33,6 +34,16 @@ public interface IChunk extends Trimable, IChunkGet, IChunkSet {
*/ */
int getZ(); int getZ();
/**
* Return the minimum block coordinate of the chunk
*
* @return BlockVector3 of minimum block coordinate
* @since 2.8.4
*/
default BlockVector3 getChunkBlockCoord() {
return BlockVector3.at(getX() << 4, getMinY(), getZ() << 4);
}
/** /**
* If the chunk is a delegate, returns its parent's root * If the chunk is a delegate, returns its parent's root
* *

Datei anzeigen

@ -18,6 +18,7 @@ import com.fastasyncworldedit.core.queue.Filter;
import com.fastasyncworldedit.core.queue.IQueueChunk; import com.fastasyncworldedit.core.queue.IQueueChunk;
import com.fastasyncworldedit.core.queue.IQueueExtent; import com.fastasyncworldedit.core.queue.IQueueExtent;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.BlockMask; import com.sk89q.worldedit.function.mask.BlockMask;
import com.sk89q.worldedit.function.mask.ExistingBlockMask; import com.sk89q.worldedit.function.mask.ExistingBlockMask;
@ -45,6 +46,7 @@ import java.util.stream.IntStream;
public class ParallelQueueExtent extends PassthroughExtent { public class ParallelQueueExtent extends PassthroughExtent {
private static final Logger LOGGER = LogManagerCompat.getLogger(); private static final Logger LOGGER = LogManagerCompat.getLogger();
private static final ThreadLocal<Extent> extents = new ThreadLocal<>();
private final World world; private final World world;
private final QueueHandler handler; private final QueueHandler handler;
@ -73,10 +75,36 @@ public class ParallelQueueExtent extends PassthroughExtent {
this.fastmode = fastmode; this.fastmode = fastmode;
} }
/**
* Removes the extent currently associated with the calling thread.
*/
public static void clearCurrentExtent() {
extents.remove();
}
/**
* Sets the extent associated with the calling thread.
*/
public static void setCurrentExtent(Extent extent) {
extents.set(extent);
}
private void enter(Extent extent) {
setCurrentExtent(extent);
}
private void exit() {
clearCurrentExtent();
}
@Override @Override
@SuppressWarnings({"unchecked", "rawtypes"}) @SuppressWarnings({"unchecked", "rawtypes"})
public IQueueExtent<IQueueChunk> getExtent() { public IQueueExtent<IQueueChunk> getExtent() {
return (IQueueExtent<IQueueChunk>) super.getExtent(); Extent extent = extents.get();
if (extent == null) {
extent = super.getExtent();
}
return (IQueueExtent<IQueueChunk>) extent;
} }
@Override @Override
@ -114,6 +142,7 @@ public class ParallelQueueExtent extends PassthroughExtent {
final SingleThreadQueueExtent queue = (SingleThreadQueueExtent) getNewQueue(); final SingleThreadQueueExtent queue = (SingleThreadQueueExtent) getNewQueue();
queue.setFastMode(fastmode); queue.setFastMode(fastmode);
queue.setFaweExceptionArray(faweExceptionReasonsUsed); queue.setFaweExceptionArray(faweExceptionReasonsUsed);
enter(queue);
synchronized (queue) { synchronized (queue) {
try { try {
ChunkFilterBlock block = null; ChunkFilterBlock block = null;
@ -154,6 +183,8 @@ public class ParallelQueueExtent extends PassthroughExtent {
exceptionCount++; exceptionCount++;
LOGGER.warn(message); LOGGER.warn(message);
} }
} finally {
exit();
} }
})).toArray(ForkJoinTask[]::new); })).toArray(ForkJoinTask[]::new);
// Join filters // Join filters

Datei anzeigen

@ -68,7 +68,8 @@ public abstract class QueueHandler implements Trimable, Runnable {
* Main "work-horse" queue for FAWE. Handles chunk submission (and chunk submission alone). Blocking in order to forcibly * Main "work-horse" queue for FAWE. Handles chunk submission (and chunk submission alone). Blocking in order to forcibly
* prevent overworking/over-submission of chunk process tasks. * prevent overworking/over-submission of chunk process tasks.
*/ */
private final ThreadPoolExecutor blockingExecutor = FaweCache.INSTANCE.newBlockingExecutor(); private final ThreadPoolExecutor blockingExecutor = FaweCache.INSTANCE.newBlockingExecutor(
"FAWE QueueHandler Blocking Executor - %d");
/** /**
* Queue for tasks to be completed on the main thread. These take priority of tasks submitted to syncWhenFree queue * Queue for tasks to be completed on the main thread. These take priority of tasks submitted to syncWhenFree queue
*/ */
@ -407,7 +408,7 @@ public abstract class QueueHandler implements Trimable, Runnable {
* Sets the current thread's {@link IQueueExtent} instance in the queue pool to null. * Sets the current thread's {@link IQueueExtent} instance in the queue pool to null.
*/ */
public void unCache() { public void unCache() {
queuePool.set(null); queuePool.remove();
} }
private IQueueExtent<IQueueChunk> pool() { private IQueueExtent<IQueueChunk> pool() {

Datei anzeigen

@ -9,7 +9,6 @@ import com.fastasyncworldedit.core.extent.processor.EmptyBatchProcessor;
import com.fastasyncworldedit.core.extent.processor.ExtentBatchProcessorHolder; import com.fastasyncworldedit.core.extent.processor.ExtentBatchProcessorHolder;
import com.fastasyncworldedit.core.extent.processor.ProcessorScope; import com.fastasyncworldedit.core.extent.processor.ProcessorScope;
import com.fastasyncworldedit.core.internal.exception.FaweException; import com.fastasyncworldedit.core.internal.exception.FaweException;
import com.fastasyncworldedit.core.queue.IChunk;
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.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IChunkSet;
@ -48,11 +47,9 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
private static final Logger LOGGER = LogManagerCompat.getLogger(); private static final Logger LOGGER = LogManagerCompat.getLogger();
// Pool discarded chunks for reuse (can safely be cleared by another thread)
// private static final ConcurrentLinkedQueue<IChunk> CHUNK_POOL = new ConcurrentLinkedQueue<>();
// Chunks currently being queued / worked on // Chunks currently being queued / worked on
private final Long2ObjectLinkedOpenHashMap<IQueueChunk> chunks = new Long2ObjectLinkedOpenHashMap<>(); private final Long2ObjectLinkedOpenHashMap<IQueueChunk<?>> chunks = new Long2ObjectLinkedOpenHashMap<>();
private final ConcurrentLinkedQueue<Future> submissions = new ConcurrentLinkedQueue<>(); private final ConcurrentLinkedQueue<Future<?>> submissions = new ConcurrentLinkedQueue<>();
private final ReentrantLock getChunkLock = new ReentrantLock(); private final ReentrantLock getChunkLock = new ReentrantLock();
private World world = null; private World world = null;
private int minY = 0; private int minY = 0;
@ -142,12 +139,10 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
if (!this.initialized) { if (!this.initialized) {
return; return;
} }
if (!this.chunks.isEmpty()) { getChunkLock.lock();
getChunkLock.lock(); try {
for (IChunk chunk : this.chunks.values()) {
chunk.recycle();
}
this.chunks.clear(); this.chunks.clear();
} finally {
getChunkLock.unlock(); getChunkLock.unlock();
} }
this.enabledQueue = true; this.enabledQueue = true;
@ -158,6 +153,7 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
this.setProcessor(EmptyBatchProcessor.getInstance()); this.setProcessor(EmptyBatchProcessor.getInstance());
this.setPostProcessor(EmptyBatchProcessor.getInstance()); this.setPostProcessor(EmptyBatchProcessor.getInstance());
this.world = null; this.world = null;
this.faweExceptionReasonsUsed = new boolean[FaweException.Type.values().length];
} }
/** /**
@ -233,7 +229,6 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
} }
} }
if (chunk.isEmpty()) { if (chunk.isEmpty()) {
chunk.recycle();
Future result = Futures.immediateFuture(null); Future result = Futures.immediateFuture(null);
return (V) result; return (V) result;
} }

Datei anzeigen

@ -1,7 +1,5 @@
package com.fastasyncworldedit.core.queue.implementation.chunk; package com.fastasyncworldedit.core.queue.implementation.chunk;
import com.fastasyncworldedit.core.FaweCache;
import com.fastasyncworldedit.core.configuration.Settings;
import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock; import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock;
import com.fastasyncworldedit.core.extent.processor.EmptyBatchProcessor; import com.fastasyncworldedit.core.extent.processor.EmptyBatchProcessor;
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
@ -11,35 +9,34 @@ import com.fastasyncworldedit.core.queue.IChunkGet;
import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IChunkSet;
import com.fastasyncworldedit.core.queue.IQueueChunk; import com.fastasyncworldedit.core.queue.IQueueChunk;
import com.fastasyncworldedit.core.queue.IQueueExtent; import com.fastasyncworldedit.core.queue.IQueueExtent;
import com.fastasyncworldedit.core.queue.Pool; import com.fastasyncworldedit.core.queue.implementation.ParallelQueueExtent;
import com.fastasyncworldedit.core.util.MemUtil;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
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.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import org.apache.logging.log4j.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
/** /**
* An abstract {@link IChunk} class that implements basic get/set blocks. * An abstract {@link IChunk} class that implements basic get/set blocks.
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> { public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
private static final Logger LOGGER = LogManagerCompat.getLogger();
private static final Pool<ChunkHolder> POOL = FaweCache.INSTANCE.registerPool(
ChunkHolder.class,
ChunkHolder::new,
Settings.settings().QUEUE.POOL
);
public static ChunkHolder newInstance() { public static ChunkHolder newInstance() {
return POOL.poll(); return new ChunkHolder();
} }
private volatile IChunkGet chunkExisting; // The existing chunk (e.g. a clipboard, or the world, before changes) private volatile IChunkGet chunkExisting; // The existing chunk (e.g. a clipboard, or the world, before changes)
@ -62,16 +59,12 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
this.delegate = delegate; this.delegate = delegate;
} }
private static final AtomicBoolean recycleWarning = new AtomicBoolean(false);
@Override @Override
public synchronized void recycle() { public void recycle() {
delegate = NULL; if (!recycleWarning.getAndSet(true)) {
if (chunkSet != null) { LOGGER.warn("ChunkHolder should not be recycled.", new Exception());
chunkSet.recycle();
chunkSet = null;
} }
chunkExisting = null;
extent = null;
POOL.offer(this);
} }
public long initAge() { public long initAge() {
@ -959,7 +952,7 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
public final IChunkGet getOrCreateGet() { public final IChunkGet getOrCreateGet() {
if (chunkExisting == null) { if (chunkExisting == null) {
chunkExisting = newWrappedGet(); chunkExisting = newWrappedGet();
chunkExisting.trim(false); chunkExisting.trim(MemUtil.isMemoryLimited());
} }
return chunkExisting; return chunkExisting;
} }
@ -1017,7 +1010,6 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
// Do nothing // Do nothing
}); });
} }
recycle();
return null; return null;
} }
@ -1030,11 +1022,12 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
IChunkGet get = getOrCreateGet(); IChunkGet get = getOrCreateGet();
try { try {
get.lockCall(); get.lockCall();
trackExtent();
boolean postProcess = !(getExtent().getPostProcessor() instanceof EmptyBatchProcessor); boolean postProcess = !(getExtent().getPostProcessor() instanceof EmptyBatchProcessor);
final int copyKey = get.setCreateCopy(postProcess);
final IChunkSet iChunkSet = getExtent().processSet(this, get, set); final IChunkSet iChunkSet = getExtent().processSet(this, get, set);
Runnable finalizer; Runnable finalizer;
if (postProcess) { if (postProcess) {
int copyKey = get.setCreateCopy(true);
finalizer = () -> { finalizer = () -> {
getExtent().postProcess(this, get.getCopy(copyKey), iChunkSet); getExtent().postProcess(this, get.getCopy(copyKey), iChunkSet);
finalize.run(); finalize.run();
@ -1045,11 +1038,24 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
return get.call(set, finalizer); return get.call(set, finalizer);
} finally { } finally {
get.unlockCall(); get.unlockCall();
untrackExtent();
} }
} }
return null; return null;
} }
// "call" can be called by QueueHandler#blockingExecutor. In such case, we still want the other thread
// to use this SingleThreadQueueExtent. Otherwise, many threads might end up locking on **one** STQE.
// This way, locking is spread across multiple STQEs, allowing for better performance
private void trackExtent() {
ParallelQueueExtent.setCurrentExtent(extent);
}
private void untrackExtent() {
ParallelQueueExtent.clearCurrentExtent();
}
/** /**
* Get the extent this chunk is in. * Get the extent this chunk is in.
*/ */

Datei anzeigen

@ -33,7 +33,7 @@ public abstract class RandomCollection<T> {
public static <T> RandomCollection<T> of(Map<T, Double> weights, SimpleRandom random) { public static <T> RandomCollection<T> of(Map<T, Double> weights, SimpleRandom random) {
checkNotNull(random); checkNotNull(random);
return FastRandomCollection.create(weights, random) return FastRandomCollection.create(weights, random)
.orElse(new SimpleRandomCollection<>(weights, random)); .orElseGet(() -> new SimpleRandomCollection<>(weights, random));
} }
public void setRandom(SimpleRandom random) { public void setRandom(SimpleRandom random) {

Datei anzeigen

@ -32,6 +32,7 @@ import com.fastasyncworldedit.core.internal.io.FaweOutputStream;
import com.fastasyncworldedit.core.limit.FaweLimit; import com.fastasyncworldedit.core.limit.FaweLimit;
import com.fastasyncworldedit.core.util.BrushCache; import com.fastasyncworldedit.core.util.BrushCache;
import com.fastasyncworldedit.core.util.MainUtil; import com.fastasyncworldedit.core.util.MainUtil;
import com.fastasyncworldedit.core.util.MaskTraverser;
import com.fastasyncworldedit.core.util.StringMan; import com.fastasyncworldedit.core.util.StringMan;
import com.fastasyncworldedit.core.util.TaskManager; import com.fastasyncworldedit.core.util.TaskManager;
import com.fastasyncworldedit.core.util.TextureHolder; import com.fastasyncworldedit.core.util.TextureHolder;
@ -53,6 +54,7 @@ import com.sk89q.worldedit.command.tool.Tool;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Locatable; import com.sk89q.worldedit.extension.platform.Locatable;
import com.sk89q.worldedit.extent.NullExtent;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.extent.inventory.BlockBag;
@ -594,6 +596,9 @@ public class LocalSession implements TextureHolder {
long size = MainUtil.getSize(item); long size = MainUtil.getSize(item);
historySize -= size; historySize -= size;
} }
// free the mask from any remaining references to e.g. extents
// if used again
new MaskTraverser(mask).reset(NullExtent.INSTANCE);
} finally { } finally {
historyWriteLock.unlock(); historyWriteLock.unlock();
} }

Datei anzeigen

@ -47,6 +47,7 @@ import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.command.util.Logging; import com.sk89q.worldedit.command.util.Logging;
import com.sk89q.worldedit.command.util.annotation.Confirm; import com.sk89q.worldedit.command.util.annotation.Confirm;
import com.sk89q.worldedit.command.util.annotation.Preload; import com.sk89q.worldedit.command.util.annotation.Preload;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
@ -70,6 +71,7 @@ import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.math.transform.AffineTransform; import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.math.transform.Transform; import com.sk89q.worldedit.math.transform.Transform;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.NullRegion; import com.sk89q.worldedit.regions.NullRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionIntersection; import com.sk89q.worldedit.regions.RegionIntersection;
@ -453,7 +455,9 @@ public class ClipboardCommands {
@Switch(name = 'e', desc = "Paste entities if available") @Switch(name = 'e', desc = "Paste entities if available")
boolean pasteEntities, boolean pasteEntities,
@Switch(name = 'b', desc = "Paste biomes if available") @Switch(name = 'b', desc = "Paste biomes if available")
boolean pasteBiomes boolean pasteBiomes,
@Switch(name = 'x', desc = "Remove existing entities in the affected region")
boolean removeEntities
) throws WorldEditException { ) throws WorldEditException {
ClipboardHolder holder = session.getClipboard(); ClipboardHolder holder = session.getClipboard();
final Clipboard clipboard = holder.getClipboard(); final Clipboard clipboard = holder.getClipboard();
@ -466,17 +470,22 @@ public class ClipboardCommands {
} }
Region region = clipboard.getRegion().clone(); Region region = clipboard.getRegion().clone();
if (selectPasted || onlySelect) { if (selectPasted || onlySelect || removeEntities) {
BlockVector3 clipboardOffset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin()); BlockVector3 clipboardOffset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
BlockVector3 realTo = to.add(holder.getTransform().apply(clipboardOffset.toVector3()).toBlockPoint()); BlockVector3 realTo = to.add(holder.getTransform().apply(clipboardOffset.toVector3()).toBlockPoint());
BlockVector3 max = realTo.add(holder BlockVector3 max = realTo.add(holder
.getTransform() .getTransform()
.apply(region.getMaximumPoint().subtract(region.getMinimumPoint()).toVector3()) .apply(region.getMaximumPoint().subtract(region.getMinimumPoint()).toVector3())
.toBlockPoint()); .toBlockPoint());
RegionSelector selector = new CuboidRegionSelector(world, realTo, max); if (removeEntities) {
session.setRegionSelector(world, selector); editSession.getEntities(new CuboidRegion(realTo, max)).forEach(Entity::remove);
selector.learnChanges(); }
selector.explainRegionAdjust(actor, session); if (selectPasted || onlySelect) {
RegionSelector selector = new CuboidRegionSelector(world, realTo, max);
session.setRegionSelector(world, selector);
selector.learnChanges();
selector.explainRegionAdjust(actor, session);
}
} }
if (onlySelect) { if (onlySelect) {
actor.print(Caption.of("worldedit.paste.selected")); actor.print(Caption.of("worldedit.paste.selected"));
@ -513,14 +522,19 @@ public class ClipboardCommands {
boolean pasteBiomes, boolean pasteBiomes,
@ArgFlag(name = 'm', desc = "Only paste blocks matching this mask") @ArgFlag(name = 'm', desc = "Only paste blocks matching this mask")
@ClipboardMask @ClipboardMask
Mask sourceMask Mask sourceMask,
//FAWE start - entity removal
@Switch(name = 'x', desc = "Remove existing entities in the affected region")
boolean removeEntities
//FAWE end
) throws WorldEditException { ) throws WorldEditException {
ClipboardHolder holder = session.getClipboard(); ClipboardHolder holder = session.getClipboard();
//FAWE start - use place //FAWE start - use place
if (holder.getTransform().isIdentity() && sourceMask == null) { if (holder.getTransform().isIdentity() && sourceMask == null) {
place(actor, world, session, editSession, ignoreAirBlocks, atOrigin, selectPasted, onlySelect, place(actor, world, session, editSession, ignoreAirBlocks, atOrigin, selectPasted, onlySelect,
pasteEntities, pasteBiomes pasteEntities, pasteBiomes, removeEntities
); );
return; return;
} }
@ -547,21 +561,29 @@ public class ClipboardCommands {
messages.addAll(Lists.newArrayList(operation.getStatusMessages())); messages.addAll(Lists.newArrayList(operation.getStatusMessages()));
} }
if (selectPasted || onlySelect) { if (selectPasted || onlySelect || removeEntities) {
BlockVector3 clipboardOffset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin()); BlockVector3 clipboardOffset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
Vector3 realTo = to.toVector3().add(holder.getTransform().apply(clipboardOffset.toVector3())); Vector3 realTo = to.toVector3().add(holder.getTransform().apply(clipboardOffset.toVector3()));
Vector3 max = realTo.add(holder Vector3 max = realTo.add(holder
.getTransform() .getTransform()
.apply(region.getMaximumPoint().subtract(region.getMinimumPoint()).toVector3())); .apply(region.getMaximumPoint().subtract(region.getMinimumPoint()).toVector3()));
final CuboidRegionSelector selector;
if (session.getRegionSelector(world) instanceof ExtendingCuboidRegionSelector) { // FAWE start - entity remova;l
selector = new ExtendingCuboidRegionSelector(world, realTo.toBlockPoint(), max.toBlockPoint()); if (removeEntities) {
} else { editSession.getEntities(new CuboidRegion(realTo.toBlockPoint(), max.toBlockPoint())).forEach(Entity::remove);
selector = new CuboidRegionSelector(world, realTo.toBlockPoint(), max.toBlockPoint()); }
if (selectPasted || onlySelect) {
//FAWE end
final CuboidRegionSelector selector;
if (session.getRegionSelector(world) instanceof ExtendingCuboidRegionSelector) {
selector = new ExtendingCuboidRegionSelector(world, realTo.toBlockPoint(), max.toBlockPoint());
} else {
selector = new CuboidRegionSelector(world, realTo.toBlockPoint(), max.toBlockPoint());
}
session.setRegionSelector(world, selector);
selector.learnChanges();
selector.explainRegionAdjust(actor, session);
} }
session.setRegionSelector(world, selector);
selector.learnChanges();
selector.explainRegionAdjust(actor, session);
} }
if (onlySelect) { if (onlySelect) {

Datei anzeigen

@ -25,27 +25,34 @@ import com.fastasyncworldedit.core.extent.HistoryExtent;
import com.fastasyncworldedit.core.extent.NullExtent; import com.fastasyncworldedit.core.extent.NullExtent;
import com.fastasyncworldedit.core.history.changeset.AbstractChangeSet; import com.fastasyncworldedit.core.history.changeset.AbstractChangeSet;
import com.fastasyncworldedit.core.internal.exception.FaweException; import com.fastasyncworldedit.core.internal.exception.FaweException;
import com.fastasyncworldedit.core.queue.Filter;
import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IBatchProcessor;
import com.fastasyncworldedit.core.util.ExtentTraverser; import com.fastasyncworldedit.core.util.ExtentTraverser;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.buffer.ForgetfulExtentBuffer; import com.sk89q.worldedit.extent.buffer.ForgetfulExtentBuffer;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.OperationQueue; import com.sk89q.worldedit.function.operation.OperationQueue;
import com.sk89q.worldedit.function.pattern.Pattern;
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;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Countable;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
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.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -84,9 +91,7 @@ public class AbstractDelegateExtent implements Extent {
@Override @Override
public BlockState getBlock(BlockVector3 position) { public BlockState getBlock(BlockVector3 position) {
//FAWE start - return coordinates return extent.getBlock(position);
return extent.getBlock(position.getX(), position.getY(), position.getZ());
//FAWE end
} }
@Override @Override
@ -96,9 +101,7 @@ public class AbstractDelegateExtent implements Extent {
@Override @Override
public BaseBlock getFullBlock(BlockVector3 position) { public BaseBlock getFullBlock(BlockVector3 position) {
//FAWE start - return coordinates return extent.getFullBlock(position);
return extent.getFullBlock(position.getX(), position.getY(), position.getZ());
//FAWE end
} }
//FAWE start //FAWE start
@ -110,9 +113,7 @@ public class AbstractDelegateExtent implements Extent {
@Override @Override
public BaseBlock getFullBlock(int x, int y, int z) { public BaseBlock getFullBlock(int x, int y, int z) {
//FAWE start - return coordinates
return extent.getFullBlock(x, y, z); return extent.getFullBlock(x, y, z);
//FAWE end
} }
@Override @Override
@ -168,6 +169,7 @@ public class AbstractDelegateExtent implements Extent {
} }
} }
//FAWE start
@Override @Override
public boolean cancel() { public boolean cancel() {
ExtentTraverser<Extent> traverser = new ExtentTraverser<>(this); ExtentTraverser<Extent> traverser = new ExtentTraverser<>(this);
@ -188,7 +190,6 @@ public class AbstractDelegateExtent implements Extent {
return true; return true;
} }
//FAWE start
@Override @Override
public void removeEntity(int x, int y, int z, UUID uuid) { public void removeEntity(int x, int y, int z, UUID uuid) {
extent.removeEntity(x, y, z, uuid); extent.removeEntity(x, y, z, uuid);
@ -225,11 +226,72 @@ public class AbstractDelegateExtent implements Extent {
} }
} }
@Override
public boolean isWorld() {
return extent.isWorld();
}
@Override
public List<Countable<BlockType>> getBlockDistribution(final Region region) {
return extent.getBlockDistribution(region);
}
@Override
public List<Countable<BlockState>> getBlockDistributionWithData(final Region region) {
return extent.getBlockDistributionWithData(region);
}
@Override @Override
public int getMaxY() { public int getMaxY() {
return extent.getMaxY(); return extent.getMaxY();
} }
@Override
public int countBlocks(final Region region, final Set<BaseBlock> searchBlocks) {
return extent.countBlocks(region, searchBlocks);
}
@Override
public int countBlocks(final Region region, final Mask searchMask) {
return extent.countBlocks(region, searchMask);
}
@Override
public <B extends BlockStateHolder<B>> int setBlocks(final Region region, final B block) throws MaxChangedBlocksException {
return extent.setBlocks(region, block);
}
@Override
public int setBlocks(final Region region, final Pattern pattern) throws MaxChangedBlocksException {
return extent.setBlocks(region, pattern);
}
@Override
public <B extends BlockStateHolder<B>> int replaceBlocks(
final Region region,
final Set<BaseBlock> filter,
final B replacement
)
throws MaxChangedBlocksException {
return extent.replaceBlocks(region, filter, replacement);
}
@Override
public int replaceBlocks(final Region region, final Set<BaseBlock> filter, final Pattern pattern) throws
MaxChangedBlocksException {
return extent.replaceBlocks(region, filter, pattern);
}
@Override
public int replaceBlocks(final Region region, final Mask mask, final Pattern pattern) throws MaxChangedBlocksException {
return extent.replaceBlocks(region, mask, pattern);
}
@Override
public int setBlocks(final Set<BlockVector3> vset, final Pattern pattern) {
return extent.setBlocks(vset, pattern);
}
@Override @Override
public int getMinY() { public int getMinY() {
return extent.getMinY(); return extent.getMinY();
@ -295,22 +357,26 @@ public class AbstractDelegateExtent implements Extent {
return this; return this;
} }
@Override
public <T extends Filter> T apply(final Region region, final T filter, final boolean full) {
return extent.apply(region, filter, full);
}
//FAWE end
protected Operation commitBefore() { protected Operation commitBefore() {
return null; return null;
} }
@Override
public BiomeType getBiomeType(int x, int y, int z) {
return extent.getBiomeType(x, y, z);
}
@Override @Override
public BiomeType getBiome(BlockVector3 position) { public BiomeType getBiome(BlockVector3 position) {
return extent.getBiome(position); return extent.getBiome(position);
} }
/*
History //FAWE start
*/ @Override
public BiomeType getBiomeType(int x, int y, int z) {
return extent.getBiomeType(x, y, z);
}
@Override @Override
public int getEmittedLight(int x, int y, int z) { public int getEmittedLight(int x, int y, int z) {
@ -341,13 +407,15 @@ public class AbstractDelegateExtent implements Extent {
new ExtentTraverser<>(this).setNext(new HistoryExtent(extent, changeSet)); new ExtentTraverser<>(this).setNext(new HistoryExtent(extent, changeSet));
} }
} }
//FAWE end
@Override @Override
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 position, T block) public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 position, T block)
throws WorldEditException { throws WorldEditException {
return extent.setBlock(position.getX(), position.getY(), position.getZ(), block); return extent.setBlock(position, block);
} }
//FAWE start
@Override @Override
public <T extends BlockStateHolder<T>> boolean setBlock( public <T extends BlockStateHolder<T>> boolean setBlock(
int x, int y, int x, int y,
@ -360,6 +428,7 @@ public class AbstractDelegateExtent implements Extent {
public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException { public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException {
return setBlock(x, y, z, getBlock(x, y, z).toBaseBlock(tile)); return setBlock(x, y, z, getBlock(x, y, z).toBaseBlock(tile));
} }
//FAWE end
@Override @Override
public boolean fullySupports3DBiomes() { public boolean fullySupports3DBiomes() {
@ -367,13 +436,14 @@ public class AbstractDelegateExtent implements Extent {
} }
@Override @Override
public boolean setBiome(int x, int y, int z, BiomeType biome) { public boolean setBiome(BlockVector3 position, BiomeType biome) {
return extent.setBiome(x, y, z, biome); return extent.setBiome(position, biome);
} }
//FAWE start
@Override @Override
public boolean setBiome(BlockVector3 position, BiomeType biome) { public boolean setBiome(int x, int y, int z, BiomeType biome) {
return extent.setBiome(position.getX(), position.getY(), position.getZ(), biome); return extent.setBiome(x, y, z, biome);
} }
@Override @Override

Datei anzeigen

@ -73,7 +73,10 @@ public interface Clipboard extends Extent, Iterable<BlockVector3>, Closeable, Fl
/** /**
* Creates a new {@link ReadOnlyClipboard}. * Creates a new {@link ReadOnlyClipboard}.
*
* @deprecated Internal use only. Use {@link BlockArrayClipboard#BlockArrayClipboard(Region)}
*/ */
@Deprecated
static Clipboard create(Region region) { static Clipboard create(Region region) {
checkNotNull(region); checkNotNull(region);
checkNotNull( checkNotNull(
@ -95,7 +98,10 @@ public interface Clipboard extends Extent, Iterable<BlockVector3>, Closeable, Fl
* - {@link DiskOptimizedClipboard} * - {@link DiskOptimizedClipboard}
* - {@link CPUOptimizedClipboard} * - {@link CPUOptimizedClipboard}
* - {@link MemoryOptimizedClipboard} * - {@link MemoryOptimizedClipboard}
*
* @deprecated Internal use only. Use {@link BlockArrayClipboard#BlockArrayClipboard(Region, UUID)}
*/ */
@Deprecated
static Clipboard create(Region region, UUID uuid) { static Clipboard create(Region region, UUID uuid) {
if (Settings.settings().CLIPBOARD.USE_DISK) { if (Settings.settings().CLIPBOARD.USE_DISK) {
return new DiskOptimizedClipboard(region, uuid); return new DiskOptimizedClipboard(region, uuid);

Datei anzeigen

@ -0,0 +1,43 @@
/*
* 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.extent.clipboard.io;
import com.sk89q.worldedit.util.formatting.text.Component;
/**
* Raised when a known exception occurs during schematic load.
*/
public final class SchematicLoadException extends RuntimeException {
private final Component message;
public SchematicLoadException(Component message) {
this.message = message;
}
/**
* Get the message of this exception as a rich text component.
*
* @return The rich message
*/
public Component getRichMessage() {
return this.message;
}
}

Datei anzeigen

@ -19,6 +19,7 @@
package com.sk89q.worldedit.extent.clipboard.io; package com.sk89q.worldedit.extent.clipboard.io;
import com.fastasyncworldedit.core.configuration.Caption;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.sk89q.jnbt.AdventureNBTConverter; import com.sk89q.jnbt.AdventureNBTConverter;
import com.sk89q.jnbt.ByteArrayTag; import com.sk89q.jnbt.ByteArrayTag;
@ -46,6 +47,7 @@ import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.DataFixer;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeTypes; import com.sk89q.worldedit.world.biome.BiomeTypes;
@ -137,9 +139,8 @@ public class SpongeSchematicReader extends NBTSchematicReader {
BlockArrayClipboard clip = readVersion1(schematicTag); BlockArrayClipboard clip = readVersion1(schematicTag);
return readVersion2(clip, schematicTag); return readVersion2(clip, schematicTag);
} }
throw new IOException("This schematic version is not supported; Version: " + schematicVersion + ", DataVersion: " + dataVersion + "." + throw new SchematicLoadException(Caption.of("worldedit.schematic.load.unsupported-version",
"It's very likely your schematic has an invalid file extension, if the schematic has been created on a version lower than" + TextComponent.of(schematicVersion)));
"1.13.2, the extension MUST be `.schematic`, elsewise the schematic can't be read properly.");
} }
@Override @Override
@ -169,6 +170,13 @@ public class SpongeSchematicReader extends NBTSchematicReader {
// Check // Check
Map<String, Tag> schematic = schematicTag.getValue(); Map<String, Tag> schematic = schematicTag.getValue();
// Be lenient about the specific nesting level of the Schematic tag
// Also allows checking the version from newer versions of the specification
if (schematic.size() == 1 && schematic.containsKey("Schematic")) {
schematicTag = requireTag(schematic, "Schematic", CompoundTag.class);
schematic = schematicTag.getValue();
}
schematicVersion = requireTag(schematic, "Version", IntTag.class).getValue(); schematicVersion = requireTag(schematic, "Version", IntTag.class).getValue();
return schematicTag; return schematicTag;
} }

Datei anzeigen

@ -24,6 +24,7 @@ import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType;
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;
@ -34,7 +35,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/ */
public class DataValidatorExtent extends AbstractDelegateExtent { public class DataValidatorExtent extends AbstractDelegateExtent {
private final World world; private final int minY;
private final int maxY;
/** /**
* Create a new instance. * Create a new instance.
@ -43,16 +45,27 @@ public class DataValidatorExtent extends AbstractDelegateExtent {
* @param world the world * @param world the world
*/ */
public DataValidatorExtent(Extent extent, World world) { public DataValidatorExtent(Extent extent, World world) {
this(extent, checkNotNull(world).getMinY(), world.getMaxY());
}
/**
* Create a new instance.
*
* @param extent The extent
* @param minY The minimum Y height to allow (inclusive)
* @param maxY The maximum Y height to allow (inclusive)
*/
public DataValidatorExtent(Extent extent, int minY, int maxY) {
super(extent); super(extent);
checkNotNull(world); this.minY = minY;
this.world = world; this.maxY = maxY;
} }
@Override @Override
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block) throws WorldEditException { public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block) throws WorldEditException {
final int y = location.getBlockY(); final int y = location.getBlockY();
final BlockType type = block.getBlockType(); final BlockType type = block.getBlockType();
if (y < world.getMinY() || y > world.getMaxY()) { if (y < minY || y > maxY) {
return false; return false;
} }
@ -64,4 +77,15 @@ public class DataValidatorExtent extends AbstractDelegateExtent {
return super.setBlock(location, block); return super.setBlock(location, block);
} }
@Override
public boolean setBiome(BlockVector3 location, BiomeType biome) {
final int y = location.getBlockY();
if (y < minY || y > maxY) {
return false;
}
return super.setBiome(location, biome);
}
} }

Datei anzeigen

@ -27,7 +27,7 @@ import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import java.util.HashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -41,7 +41,7 @@ public class RandomPattern extends AbstractPattern {
//FAWE start - SimpleRandom > Random, LHS<P> > List //FAWE start - SimpleRandom > Random, LHS<P> > List
private final SimpleRandom random; private final SimpleRandom random;
private Map<Pattern, Double> weights = new HashMap<>(); private Map<Pattern, Double> weights = new LinkedHashMap<>();
private RandomCollection<Pattern> collection; private RandomCollection<Pattern> collection;
private LinkedHashSet<Pattern> patterns = new LinkedHashSet<>(); private LinkedHashSet<Pattern> patterns = new LinkedHashSet<>();
//FAWE end //FAWE end

Datei anzeigen

@ -36,6 +36,7 @@ import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.command.InsufficientArgumentsException; import com.sk89q.worldedit.command.InsufficientArgumentsException;
import com.sk89q.worldedit.command.tool.InvalidToolBindException; import com.sk89q.worldedit.command.tool.InvalidToolBindException;
import com.sk89q.worldedit.extent.clipboard.io.SchematicLoadException;
import com.sk89q.worldedit.internal.expression.ExpressionException; import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.regions.RegionOperationException; import com.sk89q.worldedit.regions.RegionOperationException;
import com.sk89q.worldedit.util.formatting.text.Component; import com.sk89q.worldedit.util.formatting.text.Component;
@ -187,6 +188,11 @@ public class WorldEditExceptionConverter extends ExceptionConverterHelper {
throw newCommandException(Caption.of("worldedit.error.file-aborted"), e); throw newCommandException(Caption.of("worldedit.error.file-aborted"), e);
} }
@ExceptionMatch
public void convert(SchematicLoadException e) throws CommandException {
throw newCommandException(e.getRichMessage(), e);
}
@ExceptionMatch @ExceptionMatch
public void convert(WorldEditException e) throws CommandException { public void convert(WorldEditException e) throws CommandException {
throw newCommandException(e.getRichMessage(), e); throw newCommandException(e.getRichMessage(), e);

Datei anzeigen

@ -195,6 +195,33 @@ public class AffineTransform implements Transform, Serializable {
// =================================================================== // ===================================================================
// general methods // general methods
/**
* Returns the affine transform created by applying first the affine
* transform given by the parameters, then this affine transform.
*
* @return the composition this * that
*/
public AffineTransform concatenate(double o00, double o01, double o02, double o03,
double o10, double o11, double o12, double o13,
double o20, double o21, double o22, double o23) {
double n00 = m00 * o00 + m01 * o10 + m02 * o20;
double n01 = m00 * o01 + m01 * o11 + m02 * o21;
double n02 = m00 * o02 + m01 * o12 + m02 * o22;
double n03 = m00 * o03 + m01 * o13 + m02 * o23 + m03;
double n10 = m10 * o00 + m11 * o10 + m12 * o20;
double n11 = m10 * o01 + m11 * o11 + m12 * o21;
double n12 = m10 * o02 + m11 * o12 + m12 * o22;
double n13 = m10 * o03 + m11 * o13 + m12 * o23 + m13;
double n20 = m20 * o00 + m21 * o10 + m22 * o20;
double n21 = m20 * o01 + m21 * o11 + m22 * o21;
double n22 = m20 * o02 + m21 * o12 + m22 * o22;
double n23 = m20 * o03 + m21 * o13 + m22 * o23 + m23;
return new AffineTransform(
n00, n01, n02, n03,
n10, n11, n12, n13,
n20, n21, n22, n23);
}
/** /**
* Returns the affine transform created by applying first the affine * Returns the affine transform created by applying first the affine
* transform given by {@code that}, then this affine transform. * transform given by {@code that}, then this affine transform.
@ -203,22 +230,10 @@ public class AffineTransform implements Transform, Serializable {
* @return the composition this * that * @return the composition this * that
*/ */
public AffineTransform concatenate(AffineTransform that) { public AffineTransform concatenate(AffineTransform that) {
double n00 = m00 * that.m00 + m01 * that.m10 + m02 * that.m20; return concatenate(
double n01 = m00 * that.m01 + m01 * that.m11 + m02 * that.m21; that.m00, that.m01, that.m02, that.m03,
double n02 = m00 * that.m02 + m01 * that.m12 + m02 * that.m22; that.m10, that.m11, that.m12, that.m13,
double n03 = m00 * that.m03 + m01 * that.m13 + m02 * that.m23 + m03; that.m20, that.m21, that.m22, that.m23
double n10 = m10 * that.m00 + m11 * that.m10 + m12 * that.m20;
double n11 = m10 * that.m01 + m11 * that.m11 + m12 * that.m21;
double n12 = m10 * that.m02 + m11 * that.m12 + m12 * that.m22;
double n13 = m10 * that.m03 + m11 * that.m13 + m12 * that.m23 + m13;
double n20 = m20 * that.m00 + m21 * that.m10 + m22 * that.m20;
double n21 = m20 * that.m01 + m21 * that.m11 + m22 * that.m21;
double n22 = m20 * that.m02 + m21 * that.m12 + m22 * that.m22;
double n23 = m20 * that.m03 + m21 * that.m13 + m22 * that.m23 + m23;
return new AffineTransform(
n00, n01, n02, n03,
n10, n11, n12, n13,
n20, n21, n22, n23
); );
} }
@ -258,40 +273,37 @@ public class AffineTransform implements Transform, Serializable {
} }
public AffineTransform translate(double x, double y, double z) { public AffineTransform translate(double x, double y, double z) {
return concatenate(new AffineTransform(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z)); return concatenate(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z);
} }
public AffineTransform rotateX(double theta) { public AffineTransform rotateX(double theta) {
double cot = MathUtils.dCos(theta); double cot = MathUtils.dCos(theta);
double sit = MathUtils.dSin(theta); double sit = MathUtils.dSin(theta);
return concatenate( return concatenate(
new AffineTransform( 1, 0, 0, 0,
1, 0, 0, 0, 0, cot, -sit, 0,
0, cot, -sit, 0, 0, sit, cot, 0
0, sit, cot, 0 );
));
} }
public AffineTransform rotateY(double theta) { public AffineTransform rotateY(double theta) {
double cot = MathUtils.dCos(theta); double cot = MathUtils.dCos(theta);
double sit = MathUtils.dSin(theta); double sit = MathUtils.dSin(theta);
return concatenate( return concatenate(
new AffineTransform( cot, 0, sit, 0,
cot, 0, sit, 0, 0, 1, 0, 0,
0, 1, 0, 0, -sit, 0, cot, 0
-sit, 0, cot, 0 );
));
} }
public AffineTransform rotateZ(double theta) { public AffineTransform rotateZ(double theta) {
double cot = MathUtils.dCos(theta); double cot = MathUtils.dCos(theta);
double sit = MathUtils.dSin(theta); double sit = MathUtils.dSin(theta);
return concatenate( return concatenate(
new AffineTransform( cot, -sit, 0, 0,
cot, -sit, 0, 0, sit, cot, 0, 0,
sit, cot, 0, 0, 0, 0, 1, 0
0, 0, 1, 0 );
));
} }
public AffineTransform scale(double s) { public AffineTransform scale(double s) {
@ -299,7 +311,7 @@ public class AffineTransform implements Transform, Serializable {
} }
public AffineTransform scale(double sx, double sy, double sz) { public AffineTransform scale(double sx, double sy, double sz) {
return concatenate(new AffineTransform(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0)); return concatenate(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0);
} }
public AffineTransform scale(Vector3 vec) { public AffineTransform scale(Vector3 vec) {
@ -352,9 +364,9 @@ public class AffineTransform implements Transform, Serializable {
//FAWE start - check other identity //FAWE start - check other identity
if (other instanceof Identity || other.isIdentity()) { if (other instanceof Identity || other.isIdentity()) {
return this; return this;
} else if (other instanceof AffineTransform) { } else if (other instanceof AffineTransform otherTransform) {
//FAWE end //FAWE end
return concatenate((AffineTransform) other); return concatenate(otherTransform);
} else { } else {
return new CombinedTransform(this, other); return new CombinedTransform(this, other);
} }

Datei anzeigen

@ -22,7 +22,6 @@ package com.sk89q.worldedit.regions;
import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.configuration.Settings;
import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock; import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock;
import com.fastasyncworldedit.core.math.BlockVectorSet; import com.fastasyncworldedit.core.math.BlockVectorSet;
import com.fastasyncworldedit.core.math.MutableBlockVector2;
import com.fastasyncworldedit.core.math.MutableBlockVector3; import com.fastasyncworldedit.core.math.MutableBlockVector3;
import com.fastasyncworldedit.core.queue.Filter; import com.fastasyncworldedit.core.queue.Filter;
import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunk;
@ -805,7 +804,8 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
return set; return set;
} }
trimY(set, minY, maxY, true); trimY(set, minY, maxY, true);
trimNBT(set, this::contains); BlockVector3 chunkPos = chunk.getChunkBlockCoord().withY(0);
trimNBT(set, this::contains, pos -> this.contains(pos.add(chunkPos)));
return set; return set;
} }
if (tx >= minX && bx <= maxX && tz >= minZ && bz <= maxZ) { if (tx >= minX && bx <= maxX && tz >= minZ && bz <= maxZ) {
@ -868,8 +868,8 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
} }
set.setBlocks(layer, arr); set.setBlocks(layer, arr);
} }
final BlockVector3 chunkPos = BlockVector3.at(chunk.getX() << 4, 0, chunk.getZ() << 4);
trimNBT(set, this::contains); trimNBT(set, this::contains, pos -> this.contains(pos.add(chunkPos)));
return set; return set;
} }
return null; return null;
@ -893,7 +893,8 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
return null; return null;
} }
trimY(set, minY, maxY, false); trimY(set, minY, maxY, false);
trimNBT(set, this::contains); BlockVector3 chunkPos = chunk.getChunkBlockCoord().withY(0);
trimNBT(set, this::contains, pos -> this.contains(pos.add(chunkPos)));
return set; return set;
} }
if (tx >= minX && bx <= maxX && tz >= minZ && bz <= maxZ) { if (tx >= minX && bx <= maxX && tz >= minZ && bz <= maxZ) {
@ -943,7 +944,8 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
} }
set.setBlocks(layer, arr); set.setBlocks(layer, arr);
} }
trimNBT(set, bv3 -> !this.contains(bv3)); BlockVector3 chunkPos = chunk.getChunkBlockCoord().withY(0);
trimNBT(set, bv3 -> !this.contains(bv3), bv3 -> !this.contains(bv3.add(chunkPos)));
return set; return set;
} }
return set; return set;

Datei anzeigen

@ -141,7 +141,7 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion {
*/ */
public void setRadius(Vector2 radius) { public void setRadius(Vector2 radius) {
this.radius = radius.add(0.5, 0.5); this.radius = radius.add(0.5, 0.5);
this.radiusInverse = Vector2.ONE.divide(radius); this.radiusInverse = Vector2.ONE.divide(this.radius);
} }
/** /**
@ -413,11 +413,12 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion {
final IChunk chunk, final Filter filter, final ChunkFilterBlock block, final IChunk chunk, final Filter filter, final ChunkFilterBlock block,
final IChunkGet get, final IChunkSet set, boolean full final IChunkGet get, final IChunkSet set, boolean full
) { ) {
int bcx = chunk.getX() >> 4; int bcx = chunk.getX() << 4;
int bcz = chunk.getZ() >> 4; int bcz = chunk.getZ() << 4;
int tcx = bcx + 15; int tcx = bcx + 15;
int tcz = bcz + 15; int tcz = bcz + 15;
if (contains(bcx, bcz) && contains(tcx, tcz)) { // must contain all 4 corners for fast path
if (contains(bcx, bcz) && contains(tcx, tcz) && contains(bcx, tcz) && contains(tcx, bcz)) {
filter(chunk, filter, block, get, set, minY, maxY, full); filter(chunk, filter, block, get, set, minY, maxY, full);
return; return;
} }

Datei anzeigen

@ -425,7 +425,8 @@ public interface Region extends Iterable<BlockVector3>, Cloneable, IBatchProcess
} }
} }
if (processExtra) { if (processExtra) {
trimNBT(set, this::contains); BlockVector3 chunkPos = chunk.getChunkBlockCoord().withY(0);
trimNBT(set, this::contains, pos -> this.contains(pos.add(chunkPos)));
} }
return set; return set;
} else { } else {
@ -477,7 +478,8 @@ public interface Region extends Iterable<BlockVector3>, Cloneable, IBatchProcess
} }
} }
if (processExtra) { if (processExtra) {
trimNBT(set, bv3 -> !this.contains(bv3)); BlockVector3 chunkPos = chunk.getChunkBlockCoord().withY(0);
trimNBT(set, bv3 -> !this.contains(bv3), bv3 -> !this.contains(bv3.add(chunkPos)));
} }
return set; return set;
} else { } else {

Datei anzeigen

@ -178,9 +178,18 @@ public class BlockState implements BlockStateHolder<BlockState>, Pattern {
String name = property.getName(); String name = property.getName();
charSequence.setSubstring(propStrStart + name.length() + 2, state.length() - 1); charSequence.setSubstring(propStrStart + name.length() + 2, state.length() - 1);
int index = charSequence.length() <= 0 ? -1 : property.getIndexFor(charSequence); try {
if (index != -1) { int index = charSequence.length() <= 0 ? -1 : property.getIndexFor(charSequence);
return type.withPropertyId(index); if (index != -1) {
return type.withPropertyId(index);
}
} catch (Exception e) {
throw new InputParseException(Caption.of(
"fawe.error.invalid-block-state-property",
TextComponent.of(charSequence.toString()),
TextComponent.of(name),
TextComponent.of(state)
), e);
} }
} }
int stateId; int stateId;
@ -200,7 +209,17 @@ public class BlockState implements BlockStateHolder<BlockState>, Pattern {
case ',': { case ',': {
charSequence.setSubstring(last, i); charSequence.setSubstring(last, i);
if (property != null) { if (property != null) {
int index = property.getIndexFor(charSequence); int index;
try {
index = property.getIndexFor(charSequence);
} catch (Exception e) {
throw new InputParseException(Caption.of(
"fawe.error.invalid-block-state-property",
TextComponent.of(charSequence.toString()),
TextComponent.of(property.getName()),
TextComponent.of(state)
), e);
}
if (index == -1) { if (index == -1) {
throw SuggestInputParseException.of(charSequence.toString(), (List<Object>) property.getValues()); throw SuggestInputParseException.of(charSequence.toString(), (List<Object>) property.getValues());
} }

Datei anzeigen

@ -92,6 +92,7 @@
"fawe.error.parser.invalid-data": "Invalid data: {0}", "fawe.error.parser.invalid-data": "Invalid data: {0}",
"fawe.error.unsupported": "Unsupported!", "fawe.error.unsupported": "Unsupported!",
"fawe.error.invalid-block-type": "Does not match a valid block type: {0}", "fawe.error.invalid-block-type": "Does not match a valid block type: {0}",
"fawe.error.invalid-block-state-property": "Cannot parse value `{0}` for property `{1}`, block state: `{2}`",
"fawe.error.nbt.forbidden": "You are not allowed to use nbt. Lacking permission: {0}", "fawe.error.nbt.forbidden": "You are not allowed to use nbt. Lacking permission: {0}",
"fawe.error.invalid-arguments": "Invalid amount of arguments. Expected: {0}", "fawe.error.invalid-arguments": "Invalid amount of arguments. Expected: {0}",
"fawe.error.unrecognised-tag": "Unrecognised tag: {0} {1}", "fawe.error.unrecognised-tag": "Unrecognised tag: {0} {1}",
@ -353,6 +354,7 @@
"worldedit.schematic.unknown-format": "Unknown schematic format: {0}.", "worldedit.schematic.unknown-format": "Unknown schematic format: {0}.",
"worldedit.schematic.load.does-not-exist": "Schematic {0} does not exist!", "worldedit.schematic.load.does-not-exist": "Schematic {0} does not exist!",
"worldedit.schematic.load.loading": "(Please wait... loading schematic.)", "worldedit.schematic.load.loading": "(Please wait... loading schematic.)",
"worldedit.schematic.load.unsupported-version": "This schematic is not supported. Version: {0}.",
"worldedit.schematic.save.already-exists": "That schematic already exists. Use the -f flag to overwrite it.", "worldedit.schematic.save.already-exists": "That schematic already exists. Use the -f flag to overwrite it.",
"worldedit.schematic.save.failed-directory": "Could not create folder for schematics!", "worldedit.schematic.save.failed-directory": "Could not create folder for schematics!",
"worldedit.schematic.save.saving": "(Please wait... saving schematic.)", "worldedit.schematic.save.saving": "(Please wait... saving schematic.)",

Datei anzeigen

@ -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.8.0") testImplementation("org.mockito:mockito-core:5.11.0")
} }
<<<<<<< HEAD <<<<<<< HEAD