Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-11-03 01:50:07 +01:00
feat!: Update for 1.18 (#1482)
* ci: Switch deployment to gh actions and use semver & java 17
* build: Update core dependencies
- Drop paranamer, you can access parameter names at runtime with Java 8+ natively
* ci: Snapshot builds are the default
* ci: Cleanup and finish transition
* ci: Trigger initial sync with the OSSRH
* revert: OSSRH snapshot deployment was successful, returning to baseline
This reverts commit 3a189f65f2
.
* ci: Register javadoc jar for lib artifacts
* ci: Sign artifacts
* build: Set kotlin jvm toolchain
* style: Use minimized `version` output
* feat: Setup project structure for 1.18
* Exclude 1.17
* Port initial paperweight classes to 1.18 folder structure
* Move to Paper 1.18
* Update templates, address JEP deprecations and place a few TODOs
* Drop Guava 21 enforcement
* Make 1.18 to be effectively in a usable state (#1452)
* Update swathes of easy-to-update-sort-of-code.
- Untested
- Should compile but NMF broken something
- Several todos:
- biome history//better support (move to biome sections in core)
- regen (haha lol no thanks, someone else can do that)
- probably actually do the palette stuff that probably won't work in PaperweightPlatformAdapter
* ci: Provide basic Jenkinsfile for ghprb pipeline
* build: Update paperweight
* upstream: Update Upstream
de6fa17 Add getBrush helper for use with instanceof pattern matching (1926)
* FAWE will now load on startup
* it....works?
* Begin to allow biome edits (and fix biomes reverting to plains upon editing blocks)
* Add new blocks/block properties
* Only create biome palette if supplies is null
* Fix biome operations
* Finally get removing BlockID done (major version change allows it)
* refactor!: Drop PlotSquared v4
Fawe 2.0.0 and newer requires Java 17, PlotSquared v4 supports 1.13 and 1.14, Fawe wont work on these versions nevertheless and refuses to load due Java version incompatiblities with older versions. Newer versions can use PlotSquared v6.
* docs: Update readme
* Added and removed some comments
* Added and removed some comments
* refactor: Rename worldedit configuration
* build: Re-add 1.17 module
This the a very nasty commit
* chore: Implement missing methods
* build: Update paperweight
* upstream: Update upstream
6df194e Remove finalize, use a Cleaner instead (1943)
9843a4f Fix snapshots in 1.18 (1959)
* ci: Escape workflows
* build: Update paperweight to 1.18.1
* build: Update Paster
* Fix compilation
* Bump to 1.18.1
* Do both 1.18 and 1.18.1
Co-authored-by: Alex <mc.cache@web.de>
* Fix single-block lookups
* Reserve ordinals 0 through 3 for air/"reserved"
* Create block palette data with values
* Fix classpath for testing for starlight
* Correctly use block rather than sky light layer [not used in paper]
Co-authored-by: NotMyFault <mc.cache@web.de>
Co-authored-by: Matt <4009945+MattBDev@users.noreply.github.com>
* Update version (checking) for semver
* build: Fix release drafter base branch
* Trigger GHPRB
* tests: Add resource pack methods
* build: Update paperweight and add 1.17 again
* chore: Lazily change build delimiter
* build: Deploy API snapshots for 2.0.0
* Update adapters jar
* More verbosely get block data and ensure biome layer isn't null
* refactor: Address a few `TODO 1.18`'s
(cherry picked from commit 0b77932b6e46c825d78b8c7ccae2a68ad890564e)
* fix: Fix `/fawe debugpaste`
* refactor! Remove deprecations marked for removal that are not present in upstream (#1483)
* Reverse a "debug" change to BukkitImplLoader
* Fix parsing of build in FaweVersion
* refactor: Do prepared statements properly
- Update TextureUtil client jar to 1.18.1
- Limit the update checker to our domain
* Add classes with the correct minor version to the start of the adapter candidates list
* refactor: Deprecate `IMP` initializors in favor of builders
* Fix WEManager (#1487)
* Fix WeManager?
* Fix WeManager?
* Also register WEManager if not available, like TaskManager.
* refactor: Also deprecated `IMP` for DBHandler
* feat: Add a bunch of new types to the flora generator
* use spigot-compatible palette constructor
* use spigot-compatible packet constructor
* implement 1.18 regen
* return air instead of reserved on get blocks
* refactor: Shift `FileAlreadyExistsException` catch to a higher level
* read the actual block from ZeroBitStorage
* Add get default version min/max world height to platform
- Fixes #1500
* Add methods to CLIPlatform
* Fix #1490
* Fix tests
* Don't force tick limiter enable/disable
* Use Math.floor instead of int cast 757bef1f7d2b16317ab3d18427ad22183344e28d
* More precise method names in MinecraftVersion
- Also ensure correct comparisons are made in FaweBukkit and BukkitServerInterface
- Fixes #1504
* Add back statically-set reserved IDs for air blocks only, make it clear they're "reserved" (#1502)
* Add back statically-set reserved IDs for air blocks only, make it clear they're "reserved"
Also:
- Ensure that reserved is never returned in GET block operations
- "empty" thus doesn't exist in the GET update methods; remove the needless checks
- Allow GET/SET chunks to determine their own default values for non-present blocks/sections
* Add comments
* Remove mentions of NMS from compilation instruction
* Update log4j version, update jd links to use "latest"
* Move to BinaryTags where appropriate in adapters
* Add comments to changed code
* Rename worldedit to fawe where appropriate
* Use new language features
* chore: Format our loggers properly
* Remove unneeded comments
* Replace CachedChange class with record
* Remove/add some more comments
* Remove remaining keywords frm CachedChanged. IJ doesn't warn?
* Compress switch statements a bit using enhanced
* More enhanced switches
* Refactor: getVersionMin/MaxY -> versionMin/MaxY
* Throw, catch, and rethrow our own exception to make sure we're finding the culprit to a possible shaded-FAWE.
* Don't wrap Exception thrown upon invalid schematic path inside a RuntimeException
Fixes #1506
* docs: Put `since` annotation on newly introduced API
* docs: Drop clarified todos
* Warn user if using small-edit history setting with extended world heights
* Refactor: add javadoc to Clipboard#create and improve variables when delegating to another paste method
* Fix issue with offset/origin when pasting a clipboard via API without wrapping into a BlockArrayClipboard
* build: Remove drop our maven repository
* docs: Fix deprecation tag
* Fix incorrect toNative method in 1.17 adapter
* refactor: Deprecate tick limiter API for public use
* ci: dordsor does love rebasing here too
* docs: Document annotations
* Update upstream
fb5ec19 Fix error for snapshot restore missing chunk
* docs: Document a few undocumented annotations
* feat: Add worldedit.schematic.list.other permission and functionality (#1507)
* Add worldedit.schematic.list.other permission and functionality
* Implement StringMan#containsUuid
* Javadocs
* chore: Add since annotation
Co-authored-by: NotMyFault <mc.cache@web.de>
Co-authored-by: NotMyFault <mc.cache@web.de>
Co-authored-by: Matt <4009945+MattBDev@users.noreply.github.com>
Co-authored-by: Aurélien <43724816+Aurelien30000@users.noreply.github.com>
Co-authored-by: SirYwell <hannesgreule@outlook.de>
Co-authored-by: JOO200 <github@joo200.de>
Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Dieser Commit ist enthalten in:
Commit
8b973da7ee
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -83,7 +83,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Fawe Version
|
label: Fawe Version
|
||||||
description: What version of Fawe are you running? (`/version FastAsyncWorldEdit`)
|
description: What version of Fawe are you running? (`/version FastAsyncWorldEdit`)
|
||||||
placeholder: "For example: FastAsyncWorldEdit version 1.17-89;8c01959"
|
placeholder: "For example: FastAsyncWorldEdit version 2.0.0-SNAPSHOT-1"
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
|
2
.github/stale.yml
vendored
2
.github/stale.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
daysUntilStale: 60
|
daysUntilStale: 30
|
||||||
daysUntilClose: 7
|
daysUntilClose: 7
|
||||||
only: issues
|
only: issues
|
||||||
exemptLabels:
|
exemptLabels:
|
||||||
|
63
.github/workflows/build.yml
vendored
63
.github/workflows/build.yml
vendored
@ -1,34 +1,47 @@
|
|||||||
name: "build"
|
name: build
|
||||||
|
|
||||||
on: ["pull_request", "push"]
|
on: [pull_request, push]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: "ubuntu-latest"
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout Repository"
|
- name: Checkout Repository
|
||||||
uses: "actions/checkout@v2.3.4"
|
uses: actions/checkout@v2.4.0
|
||||||
- name : "Validate Gradle Wrapper"
|
- name : Validate Gradle Wrapper
|
||||||
uses : "gradle/wrapper-validation-action@v1.0.4"
|
uses : gradle/wrapper-validation-action@v1.0.4
|
||||||
- name: "Grab SHA"
|
- name: Setup Java
|
||||||
uses: "benjlevesque/short-sha@v1.2"
|
uses: actions/setup-java@v2.4.0
|
||||||
id: "short-sha"
|
|
||||||
with:
|
with:
|
||||||
length: "7"
|
distribution: temurin
|
||||||
- name: "Echo SHA"
|
cache: gradle
|
||||||
run: "echo $SHA"
|
java-version: 17
|
||||||
|
- name: Clean Build
|
||||||
|
run: ./gradlew clean build --no-daemon
|
||||||
|
- name: Determine release status
|
||||||
|
if: ${{ runner.os == 'Linux' }}
|
||||||
|
run: |
|
||||||
|
if [ "$(./gradlew properties | awk '/^version:/ { print $2; }' | grep '\-SNAPSHOT')" ]; then
|
||||||
|
echo "STATUS=snapshot" >> $GITHUB_ENV
|
||||||
|
else
|
||||||
|
echo "STATUS=release" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
- name: Publish Release
|
||||||
|
if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/major/2.0.0/1.18'}}
|
||||||
|
run: ./gradlew publishToSonatype closeSonatypeStagingRepository
|
||||||
env:
|
env:
|
||||||
SHA: "${{ steps.short-sha.outputs.sha }}"
|
ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }}
|
||||||
- name: "Setup Java"
|
ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.SONATYPE_PASSWORD }}
|
||||||
uses: "actions/setup-java@v2.3.1"
|
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SIGNING_KEY }}
|
||||||
with:
|
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SIGNING_PASSWORD }}
|
||||||
distribution: "temurin"
|
- name: Publish Snapshot
|
||||||
cache: 'gradle'
|
if: ${{ runner.os == 'Linux' && env.STATUS != 'release' && github.event_name == 'push' && github.ref == 'refs/heads/major/2.0.0/1.18' }}
|
||||||
java-version: "17"
|
run: ./gradlew publishToSonatype
|
||||||
- name: "Clean Build"
|
env:
|
||||||
run: "./gradlew clean build --no-daemon"
|
ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }}
|
||||||
|
ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.SONATYPE_PASSWORD }}
|
||||||
- name: Archive Artifacts
|
- name: Archive Artifacts
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2.3.1
|
||||||
with:
|
with:
|
||||||
name: FastAsyncWorldEdit-Bukkit-1.17-${{ env.SHA }}
|
name: FastAsyncWorldEdit-Bukkit-SNAPSHOT
|
||||||
path: worldedit-bukkit/build/libs/FastAsyncWorldEdit-Bukkit-1.17-${{ env.SHA }}.jar
|
path: worldedit-bukkit/build/libs/FastAsyncWorldEdit-Bukkit-*.jar
|
||||||
|
20
.github/workflows/rebase.yml
vendored
Normale Datei
20
.github/workflows/rebase.yml
vendored
Normale Datei
@ -0,0 +1,20 @@
|
|||||||
|
name: Rebase Pull Request
|
||||||
|
on:
|
||||||
|
issue_comment:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
rebase:
|
||||||
|
name: Rebase
|
||||||
|
if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase') && github.event.comment.author_association == 'MEMBER'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repository
|
||||||
|
uses: actions/checkout@v2.4.0
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.REBASE_TOKEN }}
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Automatic Rebase
|
||||||
|
uses: cirrus-actions/rebase@1.5
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.REBASE_TOKEN }}
|
8
.github/workflows/release-drafter.yml
vendored
8
.github/workflows/release-drafter.yml
vendored
@ -1,14 +1,14 @@
|
|||||||
name: "draft release"
|
name: draft release
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "2.0.0"
|
- main
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update_release_draft:
|
update_release_draft:
|
||||||
runs-on: "ubuntu-latest"
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: "release-drafter/release-drafter@v5.15.0"
|
- uses: release-drafter/release-drafter@v5.15.0
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
54
Annotation-Explanation.adoc
Normale Datei
54
Annotation-Explanation.adoc
Normale Datei
@ -0,0 +1,54 @@
|
|||||||
|
:toc:
|
||||||
|
:toclevels: 2
|
||||||
|
|
||||||
|
= Fawe annotations explained
|
||||||
|
|
||||||
|
If we have modified parts of the WorldEdit codebase, we considered annotating it with different styles of comments, which
|
||||||
|
are explained in this document.
|
||||||
|
|
||||||
|
== In-line annotations
|
||||||
|
|
||||||
|
[source,java]
|
||||||
|
-----------------
|
||||||
|
public static Player adapt(com.sk89q.worldedit.entity.Player player) {
|
||||||
|
//FAWE start - Get player from PlayerProxy instead of BukkitPlayer if null
|
||||||
|
player = PlayerProxy.unwrap(player);
|
||||||
|
return player == null ? null : ((BukkitPlayer) player).getPlayer();
|
||||||
|
//FAWE end
|
||||||
|
}
|
||||||
|
-----------------
|
||||||
|
The `-sources` jar retains comments, if you add the FAWE API to your maven or gradle project, you can view differences between the projects with ease.
|
||||||
|
Behind the `//FAWE start - ` you can find a comment what has been changed and why it has been changed.
|
||||||
|
|
||||||
|
== Block annotations
|
||||||
|
|
||||||
|
[source,java]
|
||||||
|
-----------------
|
||||||
|
//FAWE start
|
||||||
|
@Override
|
||||||
|
public void setPermission(String permission, boolean value) {
|
||||||
|
}
|
||||||
|
//FAWE end
|
||||||
|
-----------------
|
||||||
|
Annotations can cover whole methods or go beyond the method and wrap around several added methods.
|
||||||
|
|
||||||
|
== Package annotations
|
||||||
|
Class additions are added under the `com.fastasyncworldedit` namespace, but sometimes classes need to be added in package private.
|
||||||
|
If that is done, you can find a `package-info.java` file within the package affected that outlines FAWE added classes:
|
||||||
|
[source,java]
|
||||||
|
-----------------
|
||||||
|
/**
|
||||||
|
* The following classes are FAWE additions:
|
||||||
|
*
|
||||||
|
* @see com.sk89q.worldedit.world.block.BlockTypesCache
|
||||||
|
*/
|
||||||
|
package com.sk89q.worldedit.world.block;
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
== Undocumented annotations
|
||||||
|
Specific changes are not annotated:
|
||||||
|
|
||||||
|
* `com.fastasyncworldedit.core.configuration.Caption` in `com.sk89q.worldedit` packages have been changed from
|
||||||
|
`com.sk89q.worldedit.util.formatting.text.Text` to allow the usage of color codes for messages.
|
||||||
|
|
||||||
|
* Certain Log4J loggers have been adjusted to use the proper format of placeholders.
|
12
COMPILING.md
12
COMPILING.md
@ -1,12 +1,12 @@
|
|||||||
Compiling
|
Compiling
|
||||||
=========
|
=========
|
||||||
|
|
||||||
You can compile FastAsyncWorldEdit as long as you have some version of Java greater than or equal to 16 installed. Gradle will download JDK 16 specifically if needed,
|
You can compile FastAsyncWorldEdit as long as you have some version of Java greater than or equal to 17 installed. Gradle will download JDK 17 specifically if needed,
|
||||||
but it needs some version of Java to bootstrap from.
|
but it needs some version of Java to bootstrap from.
|
||||||
|
|
||||||
Note that if you have JRE 8 installed, Gradle will currently attempt to use that to compile, which will not work. It is easiest to uninstall JRE 8 and replace it with JDK 16.
|
Note that if you have JRE 8 installed, Gradle will currently attempt to use that to compile, which will not work. It is easiest to uninstall JRE 8 and replace it with JDK 16.
|
||||||
|
|
||||||
You can get the JDK 16 [here](https://adoptium.net/).
|
You can get the JDK 17 [here](https://adoptium.net/).
|
||||||
|
|
||||||
The build process uses Gradle, which you do *not* need to download. FastAsyncWorldEdit is a multi-module project with three active modules:
|
The build process uses Gradle, which you do *not* need to download. FastAsyncWorldEdit is a multi-module project with three active modules:
|
||||||
|
|
||||||
@ -16,10 +16,6 @@ The build process uses Gradle, which you do *not* need to download. FastAsyncWor
|
|||||||
|
|
||||||
## To compile...
|
## To compile...
|
||||||
|
|
||||||
### NMS
|
|
||||||
FastAsyncWorldEdit uses NMS (net.minecraft.server) code in a variety of spots. NMS is not distributed via maven and therefore FastAsyncWorldEdit may not build without errors if you didn't install it into your local repository beforehand.
|
|
||||||
You can do that by either running Spigot's [BuildTools](https://www.spigotmc.org/wiki/buildtools/) targeting the versions needed or using Paper's [paperclip](https://papermc.io/downloads) with `java -Dpaperclip.install=true -jar paperclip.jar`.
|
|
||||||
|
|
||||||
### On Windows
|
### On Windows
|
||||||
|
|
||||||
1. Shift + right-click the folder with FastAsyncWorldEdit's files and click "Open command prompt".
|
1. Shift + right-click the folder with FastAsyncWorldEdit's files and click "Open command prompt".
|
||||||
@ -38,13 +34,13 @@ You will find:
|
|||||||
* FastAsyncWorldEdit for Bukkit in **worldedit-bukkit/build/libs**
|
* FastAsyncWorldEdit for Bukkit in **worldedit-bukkit/build/libs**
|
||||||
* the CLI version in **worldedit-cli/build/libs**
|
* the CLI version in **worldedit-cli/build/libs**
|
||||||
|
|
||||||
If you want to use FastAsyncWorldEdit, use the `FastAsyncWorldEdit-1.17-<commitHash>` version obtained in **worldedit-bukkit/build/libs**.
|
If you want to use FastAsyncWorldEdit, use the `FastAsyncWorldEdit-<identifier>` version obtained in **worldedit-bukkit/build/libs**.
|
||||||
|
|
||||||
(The `-#` version includes FastAsyncWorldEdit + necessary libraries.)
|
(The `-#` version includes FastAsyncWorldEdit + necessary libraries.)
|
||||||
|
|
||||||
## Other commands
|
## Other commands
|
||||||
|
|
||||||
* `gradlew idea` will generate an [IntelliJ IDEA](http://www.jetbrains.com/idea/) module for each folder.
|
* `gradlew idea` will generate an [IntelliJ IDEA](https://www.jetbrains.com/idea/) module for each folder.
|
||||||
|
|
||||||
_Possibly broken_:
|
_Possibly broken_:
|
||||||
* `gradlew eclipse` will generate an [Eclipse](https://www.eclipse.org/downloads/) project for each folder.
|
* `gradlew eclipse` will generate an [Eclipse](https://www.eclipse.org/downloads/) project for each folder.
|
||||||
|
10
Jenkinsfile
vendored
10
Jenkinsfile
vendored
@ -1,10 +0,0 @@
|
|||||||
pipeline {
|
|
||||||
agent any
|
|
||||||
stages {
|
|
||||||
stage('Build pull request') {
|
|
||||||
steps {
|
|
||||||
sh './gradlew clean build'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -12,7 +12,7 @@ FastAsyncWorldEdit is a fork of WorldEdit that has huge speed and memory improve
|
|||||||
* Use it in creative, survival in single player or on your server.
|
* Use it in creative, survival in single player or on your server.
|
||||||
* Use it on your Minecraft server to fix grieving and mistakes.
|
* Use it on your Minecraft server to fix grieving and mistakes.
|
||||||
|
|
||||||
Java Edition required. FastAsyncWorldEdit is compatible with Bukkit, Spigot, Paper, and Tuinity.
|
Java Edition required. FastAsyncWorldEdit is compatible with Bukkit, Spigot and Paper.
|
||||||
|
|
||||||
## Download FastAsyncWorldEdit
|
## Download FastAsyncWorldEdit
|
||||||
* Spigot: https://www.spigotmc.org/resources/fast-async-worldedit.13932/
|
* Spigot: https://www.spigotmc.org/resources/fast-async-worldedit.13932/
|
||||||
@ -24,8 +24,8 @@ Java Edition required. FastAsyncWorldEdit is compatible with Bukkit, Spigot, Pap
|
|||||||
* [Wiki](https://github.com/IntellectualSites/FastAsyncWorldEdit-Documentation/wiki)
|
* [Wiki](https://github.com/IntellectualSites/FastAsyncWorldEdit-Documentation/wiki)
|
||||||
* [Report Issue](https://github.com/IntellectualSites/FastAsyncWorldEdit/issues)
|
* [Report Issue](https://github.com/IntellectualSites/FastAsyncWorldEdit/issues)
|
||||||
* [Crowdin (Translations)](https://intellectualsites.crowdin.com/fastasyncworldedit)
|
* [Crowdin (Translations)](https://intellectualsites.crowdin.com/fastasyncworldedit)
|
||||||
* [JavaDocs for the -bukkit module](https://ci.athion.net/job/FastAsyncWorldEdit-1.17-Bukkit-Javadocs/javadoc/)
|
* [JavaDocs for the -bukkit module](https://javadoc.io/doc/com.fastasyncworldedit/FastAsyncWorldEdit-Bukkit/latest/index.html)
|
||||||
* [JavaDocs for the -core module](https://ci.athion.net/job/FastAsyncWorldEdit-1.17-Core-Javadocs/javadoc/)
|
* [JavaDocs for the -core module](https://javadoc.io/doc/com.fastasyncworldedit/FastAsyncWorldEdit-Core/latest/index.html)
|
||||||
|
|
||||||
## Edit The Code
|
## Edit The Code
|
||||||
|
|
||||||
|
@ -2,6 +2,11 @@ import org.ajoberstar.grgit.Grgit
|
|||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
import org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
|
import org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
|
||||||
import org.gradle.api.tasks.testing.logging.TestLogEvent.FAILED
|
import org.gradle.api.tasks.testing.logging.TestLogEvent.FAILED
|
||||||
|
import java.net.URI
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("io.github.gradle-nexus.publish-plugin") version "1.1.0"
|
||||||
|
}
|
||||||
|
|
||||||
logger.lifecycle("""
|
logger.lifecycle("""
|
||||||
*******************************************
|
*******************************************
|
||||||
@ -17,7 +22,8 @@ logger.lifecycle("""
|
|||||||
*******************************************
|
*******************************************
|
||||||
""")
|
""")
|
||||||
|
|
||||||
var rootVersion by extra("1.17")
|
var rootVersion by extra("2.0.0")
|
||||||
|
var snapshot by extra("SNAPSHOT")
|
||||||
var revision: String by extra("")
|
var revision: String by extra("")
|
||||||
var buildNumber by extra("")
|
var buildNumber by extra("")
|
||||||
var date: String by extra("")
|
var date: String by extra("")
|
||||||
@ -27,11 +33,10 @@ ext {
|
|||||||
}
|
}
|
||||||
date = git.head().dateTime.format(DateTimeFormatter.ofPattern("yy.MM.dd"))
|
date = git.head().dateTime.format(DateTimeFormatter.ofPattern("yy.MM.dd"))
|
||||||
revision = "-${git.head().abbreviatedId}"
|
revision = "-${git.head().abbreviatedId}"
|
||||||
val commit: String? = git.head().abbreviatedId
|
|
||||||
buildNumber = if (project.hasProperty("buildnumber")) {
|
buildNumber = if (project.hasProperty("buildnumber")) {
|
||||||
project.properties["buildnumber"] as String
|
snapshot + "-" + project.properties["buildnumber"] as String
|
||||||
} else {
|
} else {
|
||||||
commit.toString()
|
project.properties["snapshot"] as String
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,3 +71,12 @@ allprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
applyCommonConfiguration()
|
applyCommonConfiguration()
|
||||||
|
|
||||||
|
nexusPublishing {
|
||||||
|
repositories {
|
||||||
|
sonatype {
|
||||||
|
nexusUrl.set(URI.create("https://s01.oss.sonatype.org/service/local/"))
|
||||||
|
snapshotRepositoryUrl.set(URI.create("https://s01.oss.sonatype.org/content/repositories/snapshots/"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -8,14 +8,17 @@ plugins {
|
|||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
maven {
|
|
||||||
name = "PaperMC"
|
|
||||||
url = uri("https://papermc.io/repo/repository/maven-public/")
|
|
||||||
}
|
|
||||||
maven {
|
maven {
|
||||||
name = "EngineHub"
|
name = "EngineHub"
|
||||||
url = uri("https://maven.enginehub.org/repo/")
|
url = uri("https://maven.enginehub.org/repo/")
|
||||||
}
|
}
|
||||||
|
maven {
|
||||||
|
name = "PaperMC"
|
||||||
|
url = uri("https://papermc.io/repo/repository/maven-public/")
|
||||||
|
content {
|
||||||
|
includeGroupByRegex("io\\.papermc\\..*")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val properties = Properties().also { props ->
|
val properties = Properties().also { props ->
|
||||||
@ -28,5 +31,11 @@ dependencies {
|
|||||||
implementation(gradleApi())
|
implementation(gradleApi())
|
||||||
implementation("org.ajoberstar.grgit:grgit-gradle:4.1.1")
|
implementation("org.ajoberstar.grgit:grgit-gradle:4.1.1")
|
||||||
implementation("gradle.plugin.com.github.johnrengelman:shadow:7.1.1")
|
implementation("gradle.plugin.com.github.johnrengelman:shadow:7.1.1")
|
||||||
implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.1.14")
|
implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.3.3")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvmToolchain {
|
||||||
|
(this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(17))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,7 @@ import org.gradle.kotlin.dsl.dependencies
|
|||||||
|
|
||||||
// For specific version pinning, see
|
// For specific version pinning, see
|
||||||
// https://papermc.io/repo/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/
|
// https://papermc.io/repo/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/
|
||||||
fun Project.applyPaperweightAdapterConfiguration(
|
fun Project.applyPaperweightAdapterConfiguration() {
|
||||||
paperVersion: String
|
|
||||||
) {
|
|
||||||
applyCommonConfiguration()
|
applyCommonConfiguration()
|
||||||
apply(plugin = "java-library")
|
apply(plugin = "java-library")
|
||||||
applyCommonJavaConfiguration(
|
applyCommonJavaConfiguration(
|
||||||
@ -17,7 +15,6 @@ fun Project.applyPaperweightAdapterConfiguration(
|
|||||||
apply(plugin = "io.papermc.paperweight.userdev")
|
apply(plugin = "io.papermc.paperweight.userdev")
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
paperDevBundle(paperVersion)
|
|
||||||
"implementation"(project(":worldedit-bukkit"))
|
"implementation"(project(":worldedit-bukkit"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,12 +10,7 @@ fun Project.applyCommonConfiguration() {
|
|||||||
version = rootProject.version
|
version = rootProject.version
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven {
|
|
||||||
name = "IntellectualSites"
|
|
||||||
url = uri("https://mvn.intellectualsites.com/content/groups/public/")
|
|
||||||
}
|
|
||||||
maven {
|
maven {
|
||||||
name = "EngineHub"
|
name = "EngineHub"
|
||||||
url = uri("https://maven.enginehub.org/repo/")
|
url = uri("https://maven.enginehub.org/repo/")
|
||||||
@ -32,6 +27,7 @@ fun Project.applyCommonConfiguration() {
|
|||||||
name = "Athion"
|
name = "Athion"
|
||||||
url = uri("https://ci.athion.net/plugin/repository/tools/")
|
url = uri("https://ci.athion.net/plugin/repository/tools/")
|
||||||
}
|
}
|
||||||
|
mavenLocal()
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations.all {
|
configurations.all {
|
||||||
@ -42,7 +38,7 @@ fun Project.applyCommonConfiguration() {
|
|||||||
|
|
||||||
plugins.withId("java") {
|
plugins.withId("java") {
|
||||||
the<JavaPluginExtension>().toolchain {
|
the<JavaPluginExtension>().toolchain {
|
||||||
languageVersion.set(JavaLanguageVersion.of(16))
|
languageVersion.set(JavaLanguageVersion.of(17))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,15 +50,15 @@ fun Project.applyCommonConfiguration() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
add(conf.name, "com.google.guava:guava") {
|
add(conf.name, "com.google.guava:guava") {
|
||||||
version { require("21.0") }
|
version { require("31.0.1-jre") }
|
||||||
because("Mojang provides Guava")
|
because("Mojang provides Guava")
|
||||||
}
|
}
|
||||||
add(conf.name, "com.google.code.gson:gson") {
|
add(conf.name, "com.google.code.gson:gson") {
|
||||||
version { require("2.8.0") }
|
version { require("2.8.8") }
|
||||||
because("Mojang provides Gson")
|
because("Mojang provides Gson")
|
||||||
}
|
}
|
||||||
add(conf.name, "it.unimi.dsi:fastutil") {
|
add(conf.name, "it.unimi.dsi:fastutil") {
|
||||||
version { require("8.2.1") }
|
version { require("8.5.6") }
|
||||||
because("Mojang provides FastUtil")
|
because("Mojang provides FastUtil")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean
|
|||||||
val disabledLint = listOf(
|
val disabledLint = listOf(
|
||||||
"processing", "path", "fallthrough", "serial"
|
"processing", "path", "fallthrough", "serial"
|
||||||
)
|
)
|
||||||
options.release.set(11)
|
options.release.set(17)
|
||||||
options.compilerArgs.addAll(listOf("-Xlint:all") + disabledLint.map { "-Xlint:-$it" })
|
options.compilerArgs.addAll(listOf("-Xlint:all") + disabledLint.map { "-Xlint:-$it" })
|
||||||
options.isDeprecation = true
|
options.isDeprecation = true
|
||||||
options.encoding = "UTF-8"
|
options.encoding = "UTF-8"
|
||||||
@ -32,7 +32,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean
|
|||||||
}
|
}
|
||||||
|
|
||||||
configurations.all {
|
configurations.all {
|
||||||
attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 16)
|
attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<Test>().configureEach {
|
tasks.withType<Test>().configureEach {
|
||||||
@ -60,13 +60,12 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean
|
|||||||
options.encoding = "UTF-8"
|
options.encoding = "UTF-8"
|
||||||
links(
|
links(
|
||||||
"https://javadoc.io/doc/com.google.code.findbugs/jsr305/3.0.2/",
|
"https://javadoc.io/doc/com.google.code.findbugs/jsr305/3.0.2/",
|
||||||
"https://jd.adventure.kyori.net/api/4.9.1/",
|
"https://jd.adventure.kyori.net/api/latest/",
|
||||||
"https://javadoc.io/doc/org.apache.logging.log4j/log4j-api/2.14.1/",
|
"https://javadoc.io/doc/org.apache.logging.log4j/log4j-api/latest/index.html",
|
||||||
"https://javadoc.io/doc/com.google.guava/guava/21.0/",
|
|
||||||
"https://www.antlr.org/api/Java/",
|
"https://www.antlr.org/api/Java/",
|
||||||
"https://docs.enginehub.org/javadoc/org.enginehub.piston/core/0.5.7/",
|
"https://docs.enginehub.org/javadoc/org.enginehub.piston/core/0.5.7/",
|
||||||
"https://docs.enginehub.org/javadoc/org.enginehub.piston/default-impl/0.5.7/",
|
"https://docs.enginehub.org/javadoc/org.enginehub.piston/default-impl/0.5.7/",
|
||||||
"https://papermc.io/javadocs/paper/1.17/",
|
"https://papermc.io/javadocs/paper/1.18/",
|
||||||
"https://ci.athion.net/job/FastAsyncWorldEdit-1.17-Core-Javadocs/javadoc/" // needed for other module linking
|
"https://ci.athion.net/job/FastAsyncWorldEdit-1.17-Core-Javadocs/javadoc/" // needed for other module linking
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,8 @@ import org.gradle.kotlin.dsl.invoke
|
|||||||
import org.gradle.kotlin.dsl.named
|
import org.gradle.kotlin.dsl.named
|
||||||
import org.gradle.kotlin.dsl.provideDelegate
|
import org.gradle.kotlin.dsl.provideDelegate
|
||||||
import org.gradle.kotlin.dsl.register
|
import org.gradle.kotlin.dsl.register
|
||||||
|
import org.gradle.kotlin.dsl.the
|
||||||
|
import org.gradle.plugins.signing.SigningExtension
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
fun Project.applyLibrariesConfiguration() {
|
fun Project.applyLibrariesConfiguration() {
|
||||||
@ -28,6 +30,7 @@ fun Project.applyLibrariesConfiguration() {
|
|||||||
apply(plugin = "java-base")
|
apply(plugin = "java-base")
|
||||||
apply(plugin = "maven-publish")
|
apply(plugin = "maven-publish")
|
||||||
apply(plugin = "com.github.johnrengelman.shadow")
|
apply(plugin = "com.github.johnrengelman.shadow")
|
||||||
|
apply(plugin = "signing")
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
create("shade")
|
create("shade")
|
||||||
@ -49,6 +52,7 @@ fun Project.applyLibrariesConfiguration() {
|
|||||||
dependencies {
|
dependencies {
|
||||||
exclude(dependency("com.google.guava:guava"))
|
exclude(dependency("com.google.guava:guava"))
|
||||||
exclude(dependency("com.google.code.gson:gson"))
|
exclude(dependency("com.google.code.gson:gson"))
|
||||||
|
exclude(dependency("com.google.errorprone:error_prone_annotations"))
|
||||||
exclude(dependency("org.checkerframework:checker-qual"))
|
exclude(dependency("org.checkerframework:checker-qual"))
|
||||||
exclude(dependency("org.apache.logging.log4j:log4j-api"))
|
exclude(dependency("org.apache.logging.log4j:log4j-api"))
|
||||||
exclude(dependency("com.google.code.findbugs:jsr305"))
|
exclude(dependency("com.google.code.findbugs:jsr305"))
|
||||||
@ -94,8 +98,14 @@ fun Project.applyLibrariesConfiguration() {
|
|||||||
archiveClassifier.set("sources")
|
archiveClassifier.set("sources")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This a dummy jar to comply with the requirements of the OSSRH,
|
||||||
|
// libs are not API and therefore no "proper" javadoc jar is necessary
|
||||||
|
tasks.register<Jar>("javadocJar") {
|
||||||
|
archiveClassifier.set("javadoc")
|
||||||
|
}
|
||||||
|
|
||||||
tasks.named("assemble").configure {
|
tasks.named("assemble").configure {
|
||||||
dependsOn("jar", "sourcesJar")
|
dependsOn("jar", "sourcesJar", "javadocJar")
|
||||||
}
|
}
|
||||||
|
|
||||||
project.apply<LibsConfigPluginHack>()
|
project.apply<LibsConfigPluginHack>()
|
||||||
@ -112,7 +122,7 @@ fun Project.applyLibrariesConfiguration() {
|
|||||||
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
|
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
|
||||||
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
||||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
|
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
|
||||||
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 11)
|
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17)
|
||||||
}
|
}
|
||||||
outgoing.artifact(tasks.named("jar"))
|
outgoing.artifact(tasks.named("jar"))
|
||||||
}
|
}
|
||||||
@ -127,7 +137,7 @@ fun Project.applyLibrariesConfiguration() {
|
|||||||
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
|
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
|
||||||
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
||||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
|
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
|
||||||
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 11)
|
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17)
|
||||||
}
|
}
|
||||||
outgoing.artifact(tasks.named("jar"))
|
outgoing.artifact(tasks.named("jar"))
|
||||||
}
|
}
|
||||||
@ -146,6 +156,20 @@ fun Project.applyLibrariesConfiguration() {
|
|||||||
outgoing.artifact(tasks.named("sourcesJar"))
|
outgoing.artifact(tasks.named("sourcesJar"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val javadocElements = project.configurations.register("javadocElements") {
|
||||||
|
isVisible = false
|
||||||
|
description = "Javadoc elements for libs"
|
||||||
|
isCanBeResolved = false
|
||||||
|
isCanBeConsumed = true
|
||||||
|
attributes {
|
||||||
|
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME))
|
||||||
|
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.DOCUMENTATION))
|
||||||
|
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
||||||
|
attribute(DocsType.DOCS_TYPE_ATTRIBUTE, project.objects.named(DocsType.JAVADOC))
|
||||||
|
}
|
||||||
|
outgoing.artifact(tasks.named("javadocJar"))
|
||||||
|
}
|
||||||
|
|
||||||
libsComponent.addVariantsFromConfiguration(apiElements.get()) {
|
libsComponent.addVariantsFromConfiguration(apiElements.get()) {
|
||||||
mapToMavenScope("compile")
|
mapToMavenScope("compile")
|
||||||
}
|
}
|
||||||
@ -158,6 +182,22 @@ fun Project.applyLibrariesConfiguration() {
|
|||||||
mapToMavenScope("runtime")
|
mapToMavenScope("runtime")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
libsComponent.addVariantsFromConfiguration(javadocElements.get()) {
|
||||||
|
mapToMavenScope("runtime")
|
||||||
|
}
|
||||||
|
|
||||||
|
val publishingExtension = the<PublishingExtension>()
|
||||||
|
|
||||||
|
configure<SigningExtension> {
|
||||||
|
if (!version.toString().endsWith("-SNAPSHOT")) {
|
||||||
|
val signingKey: String? by project
|
||||||
|
val signingPassword: String? by project
|
||||||
|
useInMemoryPgpKeys(signingKey, signingPassword)
|
||||||
|
isRequired
|
||||||
|
sign(publishingExtension.publications)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
configure<PublishingExtension> {
|
configure<PublishingExtension> {
|
||||||
publications {
|
publications {
|
||||||
register<MavenPublication>("maven") {
|
register<MavenPublication>("maven") {
|
||||||
@ -212,33 +252,6 @@ fun Project.applyLibrariesConfiguration() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
val nexusUsername: String? by project
|
|
||||||
val nexusPassword: String? by project
|
|
||||||
if (nexusUsername != null && nexusPassword != null) {
|
|
||||||
maven {
|
|
||||||
val releasesRepositoryUrl = "https://mvn.intellectualsites.com/content/repositories/releases/"
|
|
||||||
val snapshotRepositoryUrl = "https://mvn.intellectualsites.com/content/repositories/snapshots/"
|
|
||||||
/* Commenting this out for now - Fawe currently does not user semver or any sort of versioning that
|
|
||||||
differentiates between snapshots and releases, API & (past) deployment wise, this will come with a next major release.
|
|
||||||
url = uri(
|
|
||||||
if (version.toString().endsWith("-SNAPSHOT")) snapshotRepositoryUrl
|
|
||||||
else releasesRepositoryUrl
|
|
||||||
)
|
|
||||||
*/
|
|
||||||
url = uri(releasesRepositoryUrl)
|
|
||||||
|
|
||||||
credentials {
|
|
||||||
username = nexusUsername
|
|
||||||
password = nexusPassword
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.warn("No nexus repository is added; nexusUsername or nexusPassword is null.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import org.gradle.kotlin.dsl.named
|
|||||||
import org.gradle.kotlin.dsl.provideDelegate
|
import org.gradle.kotlin.dsl.provideDelegate
|
||||||
import org.gradle.kotlin.dsl.register
|
import org.gradle.kotlin.dsl.register
|
||||||
import org.gradle.kotlin.dsl.the
|
import org.gradle.kotlin.dsl.the
|
||||||
|
import org.gradle.plugins.signing.SigningExtension
|
||||||
|
|
||||||
fun Project.applyPlatformAndCoreConfiguration() {
|
fun Project.applyPlatformAndCoreConfiguration() {
|
||||||
applyCommonConfiguration()
|
applyCommonConfiguration()
|
||||||
@ -20,6 +21,7 @@ fun Project.applyPlatformAndCoreConfiguration() {
|
|||||||
apply(plugin = "idea")
|
apply(plugin = "idea")
|
||||||
apply(plugin = "maven-publish")
|
apply(plugin = "maven-publish")
|
||||||
apply(plugin = "com.github.johnrengelman.shadow")
|
apply(plugin = "com.github.johnrengelman.shadow")
|
||||||
|
apply(plugin = "signing")
|
||||||
|
|
||||||
applyCommonJavaConfiguration(
|
applyCommonJavaConfiguration(
|
||||||
sourcesJar = name in setOf("worldedit-core", "worldedit-bukkit"),
|
sourcesJar = name in setOf("worldedit-core", "worldedit-bukkit"),
|
||||||
@ -45,6 +47,18 @@ fun Project.applyPlatformAndCoreConfiguration() {
|
|||||||
skip()
|
skip()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val publishingExtension = the<PublishingExtension>()
|
||||||
|
|
||||||
|
configure<SigningExtension> {
|
||||||
|
if (!version.toString().endsWith("-SNAPSHOT")) {
|
||||||
|
val signingKey: String? by project
|
||||||
|
val signingPassword: String? by project
|
||||||
|
useInMemoryPgpKeys(signingKey, signingPassword)
|
||||||
|
isRequired
|
||||||
|
sign(publishingExtension.publications)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
configure<PublishingExtension> {
|
configure<PublishingExtension> {
|
||||||
publications {
|
publications {
|
||||||
register<MavenPublication>("maven") {
|
register<MavenPublication>("maven") {
|
||||||
@ -99,33 +113,6 @@ fun Project.applyPlatformAndCoreConfiguration() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
val nexusUsername: String? by project
|
|
||||||
val nexusPassword: String? by project
|
|
||||||
if (nexusUsername != null && nexusPassword != null) {
|
|
||||||
maven {
|
|
||||||
val releasesRepositoryUrl = "https://mvn.intellectualsites.com/content/repositories/releases/"
|
|
||||||
val snapshotRepositoryUrl = "https://mvn.intellectualsites.com/content/repositories/snapshots/"
|
|
||||||
/* Commenting this out for now - Fawe currently does not user semver or any sort of versioning that
|
|
||||||
differentiates between snapshots and releases, API & (past) deployment wise, this will come with a next major release.
|
|
||||||
url = uri(
|
|
||||||
if (version.toString().endsWith("-SNAPSHOT")) snapshotRepositoryUrl
|
|
||||||
else releasesRepositoryUrl
|
|
||||||
)
|
|
||||||
*/
|
|
||||||
url = uri(releasesRepositoryUrl)
|
|
||||||
|
|
||||||
credentials {
|
|
||||||
username = nexusUsername
|
|
||||||
password = nexusPassword
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.warn("No nexus repository is added; nexusUsername or nexusPassword is null.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name != "worldedit-fabric") {
|
if (name != "worldedit-fabric") {
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
[versions]
|
[versions]
|
||||||
# Minecraft expectations
|
# Minecraft expectations
|
||||||
fastutil = "8.2.1"
|
fastutil = "8.5.6"
|
||||||
log4j = "2.17.0"
|
log4j = "2.17.1"
|
||||||
guava = "21.0"
|
guava = "31.0.1-jre"
|
||||||
gson = "2.8.0"
|
gson = "2.8.8"
|
||||||
|
|
||||||
# Platform expectations
|
# Platform expectations
|
||||||
paper = "1.17.1-R0.1-SNAPSHOT"
|
paper = "1.18.1-R0.1-SNAPSHOT"
|
||||||
|
|
||||||
# Plugins
|
# Plugins
|
||||||
vault = "1.7.1"
|
vault = "1.7.1"
|
||||||
@ -20,15 +20,14 @@ residence = "4.5._13.1"
|
|||||||
towny = "0.97.5.0"
|
towny = "0.97.5.0"
|
||||||
protocollib = "4.7.0"
|
protocollib = "4.7.0"
|
||||||
plotsquaredV6 = "6.2.0"
|
plotsquaredV6 = "6.2.0"
|
||||||
plotsquaredV4 = "4.514"
|
|
||||||
redprotect = "1.9.6"
|
redprotect = "1.9.6"
|
||||||
|
|
||||||
# Third party
|
# Third party
|
||||||
flow-math = "1.0.3"
|
flow-math = "1.0.3"
|
||||||
paperlib = "1.0.7"
|
paperlib = "1.0.8-SNAPSHOT"
|
||||||
bstats = "2.2.1"
|
bstats = "2.2.1"
|
||||||
serverlib = "2.3.1"
|
serverlib = "2.3.1"
|
||||||
paster = "1.1.1"
|
paster = "1.1.3"
|
||||||
sparsebitset = "1.2"
|
sparsebitset = "1.2"
|
||||||
parallelgzip = "1.0.5"
|
parallelgzip = "1.0.5"
|
||||||
adventure = "4.9.3"
|
adventure = "4.9.3"
|
||||||
@ -39,7 +38,6 @@ rhino-runtime = "1.7.13"
|
|||||||
zstd-jni = "1.4.8-1" # Not latest as it can be difficult to obtain latest ZSTD libs
|
zstd-jni = "1.4.8-1" # Not latest as it can be difficult to obtain latest ZSTD libs
|
||||||
antlr4 = "4.9.3"
|
antlr4 = "4.9.3"
|
||||||
json-simple = "1.1.1"
|
json-simple = "1.1.1"
|
||||||
paranamer = "2.8"
|
|
||||||
jlibnoise = "1.0.0"
|
jlibnoise = "1.0.0"
|
||||||
jchronic = "0.2.4a"
|
jchronic = "0.2.4a"
|
||||||
lz4-java = "1.8.0"
|
lz4-java = "1.8.0"
|
||||||
@ -81,7 +79,6 @@ towny = { group = "com.github.TownyAdvanced", name = "Towny", version.ref = "tow
|
|||||||
protocollib = { group = "com.comphenix.protocol", name = "ProtocolLib", version.ref = "protocollib" }
|
protocollib = { group = "com.comphenix.protocol", name = "ProtocolLib", version.ref = "protocollib" }
|
||||||
plotsquaredV6Bukkit = { group = "com.plotsquared", name = "PlotSquared-Bukkit", version.ref = "plotsquaredV6" }
|
plotsquaredV6Bukkit = { group = "com.plotsquared", name = "PlotSquared-Bukkit", version.ref = "plotsquaredV6" }
|
||||||
plotsquaredV6Core = { group = "com.plotsquared", name = "PlotSquared-Core", version.ref = "plotsquaredV6" }
|
plotsquaredV6Core = { group = "com.plotsquared", name = "PlotSquared-Core", version.ref = "plotsquaredV6" }
|
||||||
plotsquaredV4 = { group = "com.github.intellectualsites.plotsquared", name = "PlotSquared-API", version.ref = "plotsquaredV4" }
|
|
||||||
redprotect = { group = "net.fabiozumbi12", name = "redprotect", version.ref = "redprotect" }
|
redprotect = { group = "net.fabiozumbi12", name = "redprotect", version.ref = "redprotect" }
|
||||||
|
|
||||||
# Third Party
|
# Third Party
|
||||||
@ -104,7 +101,6 @@ zstd = { group = "com.github.luben", name = "zstd-jni", version.ref = "zstd-jni"
|
|||||||
antlr4 = { group = "org.antlr", name = "antlr4", version.ref = "antlr4" }
|
antlr4 = { group = "org.antlr", name = "antlr4", version.ref = "antlr4" }
|
||||||
antlr4Runtime = { group = "org.antlr", name = "antlr4-runtime", version.ref = "antlr4" }
|
antlr4Runtime = { group = "org.antlr", name = "antlr4-runtime", version.ref = "antlr4" }
|
||||||
jsonSimple = { group = "com.googlecode.json-simple", name = "json-simple", version.ref = "json-simple" }
|
jsonSimple = { group = "com.googlecode.json-simple", name = "json-simple", version.ref = "json-simple" }
|
||||||
paranamer = { group = "com.thoughtworks.paranamer", name = "paranamer", version.ref = "paranamer" }
|
|
||||||
jlibnoise = { group = "com.sk89q.lib", name = "jlibnoise", version.ref = "jlibnoise" }
|
jlibnoise = { group = "com.sk89q.lib", name = "jlibnoise", version.ref = "jlibnoise" }
|
||||||
jchronic = { group = "com.sk89q", name = "jchronic", version.ref = "jchronic" }
|
jchronic = { group = "com.sk89q", name = "jchronic", version.ref = "jchronic" }
|
||||||
lz4Java = { group = "org.lz4", name = "lz4-java", version.ref = "lz4-java" }
|
lz4Java = { group = "org.lz4", name = "lz4-java", version.ref = "lz4-java" }
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
"mockito-core",
|
"mockito-core",
|
||||||
"org.antlr",
|
"org.antlr",
|
||||||
"antlr4-runtime",
|
"antlr4-runtime",
|
||||||
"paranamer",
|
|
||||||
"fastutil",
|
"fastutil",
|
||||||
"it.unimi.dsi:fastutil",
|
"it.unimi.dsi:fastutil",
|
||||||
"auto-value-annotations",
|
"auto-value-annotations",
|
||||||
|
@ -4,6 +4,7 @@ include("worldedit-libs")
|
|||||||
|
|
||||||
include("worldedit-bukkit:adapters:adapter-legacy")
|
include("worldedit-bukkit:adapters:adapter-legacy")
|
||||||
include("worldedit-bukkit:adapters:adapter-1_17_1")
|
include("worldedit-bukkit:adapters:adapter-1_17_1")
|
||||||
|
include("worldedit-bukkit:adapters:adapter-1_18")
|
||||||
|
|
||||||
listOf("bukkit", "core", "cli").forEach {
|
listOf("bukkit", "core", "cli").forEach {
|
||||||
include("worldedit-libs:$it")
|
include("worldedit-libs:$it")
|
||||||
|
@ -1,21 +1,27 @@
|
|||||||
|
applyPaperweightAdapterConfiguration()
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
java
|
java
|
||||||
}
|
}
|
||||||
|
|
||||||
applyPaperweightAdapterConfiguration(
|
|
||||||
"1.17.1-R0.1-20211210.043523-198"
|
|
||||||
)
|
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
maven {
|
maven {
|
||||||
name = "PaperMC"
|
name = "PaperMC"
|
||||||
url = uri("https://papermc.io/repo/repository/maven-public/")
|
url = uri("https://papermc.io/repo/repository/maven-public/")
|
||||||
content {
|
|
||||||
includeModule("io.papermc", "paperlib")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations.all {
|
||||||
|
attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
paperDevBundle("1.17.1-R0.1-20211219.175449-201")
|
||||||
compileOnly(libs.paperlib)
|
compileOnly(libs.paperlib)
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.bukkit.adapter.ext.fawe;
|
package com.sk89q.worldedit.bukkit.adapter.ext.fawe;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
@ -35,8 +36,10 @@ import com.sk89q.worldedit.WorldEditException;
|
|||||||
import com.sk89q.worldedit.blocks.BaseItem;
|
import com.sk89q.worldedit.blocks.BaseItem;
|
||||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||||
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2.PaperweightFaweAdapter;
|
||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
import com.sk89q.worldedit.extension.platform.Watchdog;
|
import com.sk89q.worldedit.extension.platform.Watchdog;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
@ -53,6 +56,7 @@ import com.sk89q.worldedit.registry.state.IntegerProperty;
|
|||||||
import com.sk89q.worldedit.registry.state.Property;
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
import com.sk89q.worldedit.util.Direction;
|
import com.sk89q.worldedit.util.Direction;
|
||||||
import com.sk89q.worldedit.util.SideEffect;
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
|
import com.sk89q.worldedit.util.concurrency.LazyReference;
|
||||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||||
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
|
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
|
||||||
import com.sk89q.worldedit.util.io.file.SafeFiles;
|
import com.sk89q.worldedit.util.io.file.SafeFiles;
|
||||||
@ -168,11 +172,11 @@ import static com.google.common.base.Preconditions.checkState;
|
|||||||
|
|
||||||
public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft.nbt.Tag> {
|
public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft.nbt.Tag> {
|
||||||
|
|
||||||
private final Logger logger = Logger.getLogger(getClass().getCanonicalName());
|
private final Logger LOGGER = Logger.getLogger(getClass().getCanonicalName());
|
||||||
|
|
||||||
private final Field serverWorldsField;
|
private final Field worldsField;
|
||||||
private final Method getChunkFutureMethod;
|
private final Method getChunkFutureMainThreadMethod;
|
||||||
private final Field chunkProviderExecutorField;
|
private final Field mainThreadProcessorField;
|
||||||
private final Watchdog watchdog;
|
private final Watchdog watchdog;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -188,18 +192,18 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
throw new UnsupportedClassVersionError("Not 1.17.1!");
|
throw new UnsupportedClassVersionError("Not 1.17.1!");
|
||||||
}
|
}
|
||||||
|
|
||||||
serverWorldsField = CraftServer.class.getDeclaredField("worlds");
|
worldsField = CraftServer.class.getDeclaredField("worlds");
|
||||||
serverWorldsField.setAccessible(true);
|
worldsField.setAccessible(true);
|
||||||
|
|
||||||
getChunkFutureMethod = ServerChunkCache.class.getDeclaredMethod("getChunkFutureMainThread",
|
getChunkFutureMainThreadMethod = ServerChunkCache.class.getDeclaredMethod("getChunkFutureMainThread",
|
||||||
int.class, int.class, ChunkStatus.class, boolean.class
|
int.class, int.class, ChunkStatus.class, boolean.class
|
||||||
);
|
);
|
||||||
getChunkFutureMethod.setAccessible(true);
|
getChunkFutureMainThreadMethod.setAccessible(true);
|
||||||
|
|
||||||
chunkProviderExecutorField = ServerChunkCache.class.getDeclaredField(
|
mainThreadProcessorField = ServerChunkCache.class.getDeclaredField(
|
||||||
Refraction.pickName("mainThreadProcessor", "h")
|
Refraction.pickName("mainThreadProcessor", "h")
|
||||||
);
|
);
|
||||||
chunkProviderExecutorField.setAccessible(true);
|
mainThreadProcessorField.setAccessible(true);
|
||||||
|
|
||||||
new PaperweightDataConverters(CraftMagicNumbers.INSTANCE.getDataVersion(), this).build(ForkJoinPool.commonPool());
|
new PaperweightDataConverters(CraftMagicNumbers.INSTANCE.getDataVersion(), this).build(ForkJoinPool.commonPool());
|
||||||
|
|
||||||
@ -316,9 +320,31 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
return combinedId == 0 && state.getBlockType() != BlockTypes.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId);
|
return combinedId == 0 && state.getBlockType() != BlockTypes.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock getBlock(Location location) {
|
public BlockState getBlock(Location location) {
|
||||||
checkNotNull(location);
|
Preconditions.checkNotNull(location);
|
||||||
|
|
||||||
|
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
|
||||||
|
int x = location.getBlockX();
|
||||||
|
int y = location.getBlockY();
|
||||||
|
int z = location.getBlockZ();
|
||||||
|
final ServerLevel handle = craftWorld.getHandle();
|
||||||
|
LevelChunk chunk = handle.getChunk(x >> 4, z >> 4);
|
||||||
|
final BlockPos blockPos = new BlockPos(x, y, z);
|
||||||
|
final CraftBlockData blockData = chunk.getBlockState(blockPos).createCraftBlockData();
|
||||||
|
BlockState state = BukkitAdapter.adapt(blockData);
|
||||||
|
if (state == null) {
|
||||||
|
org.bukkit.block.Block bukkitBlock = location.getBlock();
|
||||||
|
state = BukkitAdapter.adapt(bukkitBlock.getBlockData());
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock getFullBlock(Location location) {
|
||||||
|
BlockState state = getBlock(location);
|
||||||
|
|
||||||
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
|
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
|
||||||
int x = location.getBlockX();
|
int x = location.getBlockX();
|
||||||
@ -328,19 +354,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
final ServerLevel handle = craftWorld.getHandle();
|
final ServerLevel handle = craftWorld.getHandle();
|
||||||
LevelChunk chunk = handle.getChunk(x >> 4, z >> 4);
|
LevelChunk chunk = handle.getChunk(x >> 4, z >> 4);
|
||||||
final BlockPos blockPos = new BlockPos(x, y, z);
|
final BlockPos blockPos = new BlockPos(x, y, z);
|
||||||
final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos);
|
|
||||||
int internalId = Block.getId(blockData);
|
|
||||||
BlockState state = BlockStateIdAccess.getBlockStateById(internalId);
|
|
||||||
if (state == null) {
|
|
||||||
org.bukkit.block.Block bukkitBlock = location.getBlock();
|
|
||||||
state = BukkitAdapter.adapt(bukkitBlock.getBlockData());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the NBT data
|
// Read the NBT data
|
||||||
BlockEntity te = chunk.getBlockEntity(blockPos);
|
BlockEntity te = chunk.getBlockEntity(blockPos);
|
||||||
if (te != null) {
|
if (te != null) {
|
||||||
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
|
net.minecraft.nbt.CompoundTag tag = te.save(new net.minecraft.nbt.CompoundTag());
|
||||||
readTileEntityIntoTag(te, tag); // Load data
|
|
||||||
//FAWE start - BinaryTag
|
//FAWE start - BinaryTag
|
||||||
return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag));
|
return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag));
|
||||||
//FAWE end
|
//FAWE end
|
||||||
@ -418,7 +436,12 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
|
|
||||||
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
|
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
|
||||||
readEntityIntoTag(mcEntity, tag);
|
readEntityIntoTag(mcEntity, tag);
|
||||||
return new BaseEntity(com.sk89q.worldedit.world.entity.EntityTypes.get(id), (CompoundTag) toNative(tag));
|
//FAWE start - BinaryTag
|
||||||
|
return new BaseEntity(
|
||||||
|
com.sk89q.worldedit.world.entity.EntityTypes.get(id),
|
||||||
|
LazyReference.from(() -> (CompoundBinaryTag) toNativeBinary(tag))
|
||||||
|
);
|
||||||
|
//FAWE end
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -500,7 +523,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
} else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) {
|
} else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) {
|
||||||
property = new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues()));
|
property = new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues()));
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("WorldEdit needs an update to support " + state.getClass().getSimpleName());
|
throw new IllegalArgumentException("FastAsyncWorldEdit needs an update to support " + state.getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
properties.put(property.getName(), property);
|
properties.put(property.getName(), property);
|
||||||
@ -650,7 +673,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Map<String, org.bukkit.World> map = (Map<String, org.bukkit.World>) serverWorldsField.get(Bukkit.getServer());
|
Map<String, org.bukkit.World> map = (Map<String, org.bukkit.World>) worldsField.get(Bukkit.getServer());
|
||||||
map.remove("worldeditregentempworld");
|
map.remove("worldeditregentempworld");
|
||||||
} catch (IllegalAccessException ignored) {
|
} catch (IllegalAccessException ignored) {
|
||||||
}
|
}
|
||||||
@ -723,7 +746,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
List<CompletableFuture<ChunkAccess>> chunkLoadings = submitChunkLoadTasks(region, serverWorld);
|
List<CompletableFuture<ChunkAccess>> chunkLoadings = submitChunkLoadTasks(region, serverWorld);
|
||||||
BlockableEventLoop<Runnable> executor;
|
BlockableEventLoop<Runnable> executor;
|
||||||
try {
|
try {
|
||||||
executor = (BlockableEventLoop<Runnable>) chunkProviderExecutorField.get(serverWorld.getChunkSource());
|
executor = (BlockableEventLoop<Runnable>) mainThreadProcessorField.get(serverWorld.getChunkSource());
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
throw new IllegalStateException("Couldn't get executor for chunk loading.", e);
|
throw new IllegalStateException("Couldn't get executor for chunk loading.", e);
|
||||||
}
|
}
|
||||||
@ -748,8 +771,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
BlockPos pos = new BlockPos(vec.getBlockX(), vec.getBlockY(), vec.getBlockZ());
|
BlockPos pos = new BlockPos(vec.getBlockX(), vec.getBlockY(), vec.getBlockZ());
|
||||||
ChunkAccess chunk = chunks.get(new ChunkPos(pos));
|
ChunkAccess chunk = chunks.get(new ChunkPos(pos));
|
||||||
final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos);
|
final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos);
|
||||||
int internalId = Block.getId(blockData);
|
BlockStateHolder<?> state = ((PaperweightFaweAdapter) WorldEditPlugin
|
||||||
BlockStateHolder<?> state = BlockStateIdAccess.getBlockStateById(internalId);
|
.getInstance()
|
||||||
|
.getBukkitImplAdapter()).adapt(blockData);
|
||||||
Objects.requireNonNull(state);
|
Objects.requireNonNull(state);
|
||||||
BlockEntity blockEntity = chunk.getBlockEntity(pos);
|
BlockEntity blockEntity = chunk.getBlockEntity(pos);
|
||||||
if (blockEntity != null) {
|
if (blockEntity != null) {
|
||||||
@ -783,7 +807,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
chunkLoadings.add(
|
chunkLoadings.add(
|
||||||
((CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>)
|
((CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>)
|
||||||
getChunkFutureMethod.invoke(chunkManager, chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true))
|
getChunkFutureMainThreadMethod.invoke(chunkManager, chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true))
|
||||||
.thenApply(either -> either.left().orElse(null))
|
.thenApply(either -> either.left().orElse(null))
|
||||||
);
|
);
|
||||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
@ -875,7 +899,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
try {
|
try {
|
||||||
return toNativeList((net.minecraft.nbt.ListTag) foreign);
|
return toNativeList((net.minecraft.nbt.ListTag) foreign);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
logger.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e);
|
LOGGER.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e);
|
||||||
return ListBinaryTag.empty();
|
return ListBinaryTag.empty();
|
||||||
}
|
}
|
||||||
} else if (foreign instanceof net.minecraft.nbt.LongTag) {
|
} else if (foreign instanceof net.minecraft.nbt.LongTag) {
|
||||||
@ -994,7 +1018,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
|||||||
WatchdogThread.tick();
|
WatchdogThread.tick();
|
||||||
}
|
}
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
logger.log(Level.WARNING, "Failed to tick watchdog", e);
|
LOGGER.log(Level.WARNING, "Failed to tick watchdog", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,8 +11,6 @@ import com.fastasyncworldedit.core.queue.implementation.packet.ChunkPacket;
|
|||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
|
||||||
import com.sk89q.jnbt.StringTag;
|
|
||||||
import com.sk89q.jnbt.Tag;
|
import com.sk89q.jnbt.Tag;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||||
@ -40,6 +38,9 @@ import com.sk89q.worldedit.util.SideEffect;
|
|||||||
import com.sk89q.worldedit.util.SideEffectSet;
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
import com.sk89q.worldedit.util.TreeGenerator;
|
import com.sk89q.worldedit.util.TreeGenerator;
|
||||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||||
|
import com.sk89q.worldedit.util.nbt.BinaryTag;
|
||||||
|
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
||||||
|
import com.sk89q.worldedit.util.nbt.StringBinaryTag;
|
||||||
import com.sk89q.worldedit.world.RegenOptions;
|
import com.sk89q.worldedit.world.RegenOptions;
|
||||||
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;
|
||||||
@ -230,9 +231,29 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
|||||||
return Registry.BLOCK.get(new ResourceLocation(blockType.getNamespace(), blockType.getResource()));
|
return Registry.BLOCK.get(new ResourceLocation(blockType.getNamespace(), blockType.getResource()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@Deprecated
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock getBlock(Location location) {
|
public BlockState getBlock(Location location) {
|
||||||
|
Preconditions.checkNotNull(location);
|
||||||
|
|
||||||
|
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
|
||||||
|
int x = location.getBlockX();
|
||||||
|
int y = location.getBlockY();
|
||||||
|
int z = location.getBlockZ();
|
||||||
|
final ServerLevel handle = craftWorld.getHandle();
|
||||||
|
LevelChunk chunk = handle.getChunk(x >> 4, z >> 4);
|
||||||
|
final BlockPos blockPos = new BlockPos(x, y, z);
|
||||||
|
final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos);
|
||||||
|
BlockState state = adapt(blockData);
|
||||||
|
if (state == null) {
|
||||||
|
org.bukkit.block.Block bukkitBlock = location.getBlock();
|
||||||
|
state = BukkitAdapter.adapt(bukkitBlock.getBlockData());
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock getFullBlock(final Location location) {
|
||||||
Preconditions.checkNotNull(location);
|
Preconditions.checkNotNull(location);
|
||||||
|
|
||||||
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
|
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
|
||||||
@ -240,19 +261,22 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
|||||||
int y = location.getBlockY();
|
int y = location.getBlockY();
|
||||||
int z = location.getBlockZ();
|
int z = location.getBlockZ();
|
||||||
|
|
||||||
final ServerLevel serverLevel = craftWorld.getHandle();
|
final ServerLevel handle = craftWorld.getHandle();
|
||||||
LevelChunk levelChunk = serverLevel.getChunk(x >> 4, z >> 4);
|
LevelChunk chunk = handle.getChunk(x >> 4, z >> 4);
|
||||||
final BlockPos blockPos = new BlockPos(x, y, z);
|
final BlockPos blockPos = new BlockPos(x, y, z);
|
||||||
org.bukkit.block.Block bukkitBlock = location.getBlock();
|
final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos);
|
||||||
BlockState state = BukkitAdapter.adapt(bukkitBlock.getBlockData());
|
BlockState state = adapt(blockData);
|
||||||
|
if (state == null) {
|
||||||
|
org.bukkit.block.Block bukkitBlock = location.getBlock();
|
||||||
|
state = BukkitAdapter.adapt(bukkitBlock.getBlockData());
|
||||||
|
}
|
||||||
if (state.getBlockType().getMaterial().hasContainer()) {
|
if (state.getBlockType().getMaterial().hasContainer()) {
|
||||||
|
|
||||||
// Read the NBT data
|
// Read the NBT data
|
||||||
BlockEntity blockEntity = levelChunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK);
|
BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK);
|
||||||
if (blockEntity != null) {
|
if (blockEntity != null) {
|
||||||
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
|
net.minecraft.nbt.CompoundTag tag = blockEntity.save(new net.minecraft.nbt.CompoundTag());
|
||||||
blockEntity.save(tag); // readTileEntityIntoTag - load data
|
return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag));
|
||||||
return state.toBaseBlock((CompoundTag) toNative(tag));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +308,7 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
|||||||
|
|
||||||
levelChunk.removeBlockEntity(blockPos); // Force delete the old tile entity
|
levelChunk.removeBlockEntity(blockPos); // Force delete the old tile entity
|
||||||
|
|
||||||
CompoundTag compoundTag = state instanceof BaseBlock ? state.getNbtData() : null;
|
CompoundBinaryTag compoundTag = state instanceof BaseBlock ? state.getNbt() : null;
|
||||||
if (compoundTag != null || existing instanceof TileEntityBlock) {
|
if (compoundTag != null || existing instanceof TileEntityBlock) {
|
||||||
level.setBlock(blockPos, blockState, 0);
|
level.setBlock(blockPos, blockState, 0);
|
||||||
// remove tile
|
// remove tile
|
||||||
@ -293,7 +317,7 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
|||||||
// though we do not do this on the Forge version
|
// though we do not do this on the Forge version
|
||||||
BlockEntity blockEntity = level.getBlockEntity(blockPos);
|
BlockEntity blockEntity = level.getBlockEntity(blockPos);
|
||||||
if (blockEntity != null) {
|
if (blockEntity != null) {
|
||||||
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) fromNative(compoundTag);
|
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) fromNativeBinary(compoundTag);
|
||||||
tag.put("x", IntTag.valueOf(x));
|
tag.put("x", IntTag.valueOf(x));
|
||||||
tag.put("y", IntTag.valueOf(y));
|
tag.put("y", IntTag.valueOf(y));
|
||||||
tag.put("z", IntTag.valueOf(z));
|
tag.put("z", IntTag.valueOf(z));
|
||||||
@ -337,14 +361,15 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
|||||||
|
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
|
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
|
||||||
Supplier<CompoundTag> saveTag = () -> {
|
Supplier<CompoundBinaryTag> saveTag = () -> {
|
||||||
final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag();
|
final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag();
|
||||||
readEntityIntoTag(mcEntity, minecraftTag);
|
readEntityIntoTag(mcEntity, minecraftTag);
|
||||||
//add Id for AbstractChangeSet to work
|
//add Id for AbstractChangeSet to work
|
||||||
final CompoundTag tag = (CompoundTag) toNative(minecraftTag);
|
final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag);
|
||||||
final Map<String, Tag> tags = new HashMap<>(tag.getValue());
|
final Map<String, BinaryTag> tags = new HashMap<>();
|
||||||
tags.put("Id", new StringTag(id));
|
tag.keySet().forEach(key -> tags.put(key, tag.get(key)));
|
||||||
return new CompoundTag(tags);
|
tags.put("Id", StringBinaryTag.of(id));
|
||||||
|
return CompoundBinaryTag.from(tags);
|
||||||
};
|
};
|
||||||
return new LazyBaseEntity(type, saveTag);
|
return new LazyBaseEntity(type, saveTag);
|
||||||
} else {
|
} else {
|
||||||
@ -401,7 +426,7 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
|||||||
LOGGER.error("Attempted to convert {} with ID {} to char. ibdToStateOrdinal length: {}. Defaulting to air!",
|
LOGGER.error("Attempted to convert {} with ID {} to char. ibdToStateOrdinal length: {}. Defaulting to air!",
|
||||||
blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToStateOrdinal.length, e1
|
blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToStateOrdinal.length, e1
|
||||||
);
|
);
|
||||||
return 0;
|
return BlockTypesCache.ReservedIDs.AIR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -486,10 +511,10 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
|||||||
chunkPacket.setNativePacket(nmsPacket);
|
chunkPacket.setNativePacket(nmsPacket);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
FaweCache.IMP.CHUNK_FLAG.get().set(true);
|
FaweCache.INSTANCE.CHUNK_FLAG.get().set(true);
|
||||||
entityPlayer.connection.send(nmsPacket);
|
entityPlayer.connection.send(nmsPacket);
|
||||||
} finally {
|
} finally {
|
||||||
FaweCache.IMP.CHUNK_FLAG.get().set(false);
|
FaweCache.INSTANCE.CHUNK_FLAG.get().set(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -517,7 +542,7 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
|||||||
Registry.ITEM.get(ResourceLocation.tryParse(baseItemStack.getType().getId())),
|
Registry.ITEM.get(ResourceLocation.tryParse(baseItemStack.getType().getId())),
|
||||||
baseItemStack.getAmount()
|
baseItemStack.getAmount()
|
||||||
);
|
);
|
||||||
stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(baseItemStack.getNbtData())));
|
stack.setTag(((net.minecraft.nbt.CompoundTag) fromNativeBinary(baseItemStack.getNbt())));
|
||||||
return CraftItemStack.asCraftMirror(stack);
|
return CraftItemStack.asCraftMirror(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -579,7 +604,7 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
|||||||
public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) {
|
public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) {
|
||||||
final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
||||||
final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount());
|
final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount());
|
||||||
weStack.setNbtData(((CompoundTag) toNative(nmsStack.getTag())));
|
weStack.setNbt(((CompoundBinaryTag) toNativeBinary(nmsStack.getTag())));
|
||||||
return weStack;
|
return weStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +250,7 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess<Level
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
TaskManager.IMP.async(() -> TaskManager.IMP.sync(runnableVal));
|
TaskManager.taskManager().async(() -> TaskManager.taskManager().sync(runnableVal));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -269,27 +269,17 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess<Level
|
|||||||
if (Fawe.isMainThread()) {
|
if (Fawe.isMainThread()) {
|
||||||
runnableVal.run();
|
runnableVal.run();
|
||||||
} else {
|
} else {
|
||||||
TaskManager.IMP.sync(runnableVal);
|
TaskManager.taskManager().sync(runnableVal);
|
||||||
}
|
}
|
||||||
cachedChanges.clear();
|
cachedChanges.clear();
|
||||||
cachedChunksToSend.clear();
|
cachedChunksToSend.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class CachedChange {
|
private record CachedChange(
|
||||||
|
LevelChunk levelChunk,
|
||||||
private final LevelChunk levelChunk;
|
BlockPos blockPos,
|
||||||
private final BlockPos blockPos;
|
net.minecraft.world.level.block.state.BlockState blockState
|
||||||
private final net.minecraft.world.level.block.state.BlockState blockState;
|
) {
|
||||||
|
|
||||||
private CachedChange(
|
|
||||||
LevelChunk levelChunk,
|
|
||||||
BlockPos blockPos,
|
|
||||||
net.minecraft.world.level.block.state.BlockState blockState
|
|
||||||
) {
|
|
||||||
this.levelChunk = levelChunk;
|
|
||||||
this.blockPos = blockPos;
|
|
||||||
this.blockState = blockState;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ import com.sk89q.worldedit.internal.Constants;
|
|||||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import io.papermc.paper.event.block.BeaconDeactivatedEvent;
|
import io.papermc.paper.event.block.BeaconDeactivatedEvent;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
@ -151,7 +151,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
if (light != null) {
|
if (light != null) {
|
||||||
lightUpdate = true;
|
lightUpdate = true;
|
||||||
try {
|
try {
|
||||||
fillLightNibble(light, LightLayer.SKY, minSectionPosition, maxSectionPosition);
|
fillLightNibble(light, LightLayer.BLOCK, minSectionPosition, maxSectionPosition);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -419,7 +419,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
try {
|
try {
|
||||||
ServerLevel nmsWorld = serverLevel;
|
ServerLevel nmsWorld = serverLevel;
|
||||||
LevelChunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);
|
LevelChunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ);
|
||||||
boolean fastmode = set.isFastMode() && Settings.IMP.QUEUE.NO_TICK_FASTMODE;
|
boolean fastmode = set.isFastMode() && Settings.settings().QUEUE.NO_TICK_FASTMODE;
|
||||||
|
|
||||||
// Remove existing tiles. Create a copy so that we can remove blocks
|
// Remove existing tiles. Create a copy so that we can remove blocks
|
||||||
Map<BlockPos, BlockEntity> chunkTiles = new HashMap<>(nmsChunk.getBlockEntities());
|
Map<BlockPos, BlockEntity> chunkTiles = new HashMap<>(nmsChunk.getBlockEntities());
|
||||||
@ -546,25 +546,30 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Biomes
|
// Biomes
|
||||||
BiomeType[] biomes = set.getBiomes();
|
BiomeType[][] biomes = set.getBiomes();
|
||||||
if (biomes != null) {
|
if (biomes != null) {
|
||||||
// set biomes
|
// set biomes
|
||||||
ChunkBiomeContainer currentBiomes = nmsChunk.getBiomes();
|
ChunkBiomeContainer currentBiomes = nmsChunk.getBiomes();
|
||||||
if (createCopy) {
|
if (createCopy) {
|
||||||
copy.storeBiomes(currentBiomes);
|
copy.storeBiomes(currentBiomes);
|
||||||
}
|
}
|
||||||
for (int y = 0, i = 0; y < 64; y++) {
|
for (int layer = 0; layer < 16; layer++) {
|
||||||
for (int z = 0; z < 4; z++) {
|
if (biomes[layer] == null) {
|
||||||
for (int x = 0; x < 4; x++, i++) {
|
continue;
|
||||||
final BiomeType biome = biomes[i];
|
}
|
||||||
if (biome != null) {
|
for (int y = 0, i = 0; y < 4; y++) {
|
||||||
Biome nmsBiome =
|
for (int z = 0; z < 4; z++) {
|
||||||
nmsWorld.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY).get(
|
for (int x = 0; x < 4; x++, i++) {
|
||||||
ResourceLocation.tryParse(biome.getId()));
|
final BiomeType biome = biomes[layer][i];
|
||||||
if (nmsBiome == null) {
|
if (biome != null) {
|
||||||
throw new NullPointerException("BiomeBase null for BiomeType " + biome.getId());
|
Biome nmsBiome =
|
||||||
|
nmsWorld.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY).get(
|
||||||
|
ResourceLocation.tryParse(biome.getId()));
|
||||||
|
if (nmsBiome == null) {
|
||||||
|
throw new NullPointerException("BiomeBase null for BiomeType " + biome.getId());
|
||||||
|
}
|
||||||
|
currentBiomes.setBiome(x, (layer << 2) + y, z, nmsBiome);
|
||||||
}
|
}
|
||||||
currentBiomes.setBiome(x, y, z, nmsBiome);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -722,7 +727,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
nmsChunk.mustNotSave = false;
|
nmsChunk.mustNotSave = false;
|
||||||
nmsChunk.markUnsaved();
|
nmsChunk.markUnsaved();
|
||||||
// send to player
|
// send to player
|
||||||
if (Settings.IMP.LIGHTING.MODE == 0 || !Settings.IMP.LIGHTING.DELAY_PACKET_SENDING) {
|
if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) {
|
||||||
this.send(finalMask, finalLightUpdate);
|
this.send(finalMask, finalLightUpdate);
|
||||||
}
|
}
|
||||||
if (finalizer != null) {
|
if (finalizer != null) {
|
||||||
@ -731,7 +736,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (syncTasks != null) {
|
if (syncTasks != null) {
|
||||||
QueueHandler queueHandler = Fawe.get().getQueueHandler();
|
QueueHandler queueHandler = Fawe.instance().getQueueHandler();
|
||||||
Runnable[] finalSyncTasks = syncTasks;
|
Runnable[] finalSyncTasks = syncTasks;
|
||||||
|
|
||||||
// Chain the sync tasks and the callback
|
// Chain the sync tasks and the callback
|
||||||
@ -756,6 +761,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
//noinspection unchecked - required at compile time
|
||||||
return (T) (Future) queueHandler.sync(chain);
|
return (T) (Future) queueHandler.sync(chain);
|
||||||
} else {
|
} else {
|
||||||
if (callback == null) {
|
if (callback == null) {
|
||||||
@ -840,16 +846,16 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
// Section is null, return empty array
|
// Section is null, return empty array
|
||||||
if (section == null) {
|
if (section == null) {
|
||||||
data = new char[4096];
|
data = new char[4096];
|
||||||
Arrays.fill(data, (char) 1);
|
Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
if (data != null && data.length != 4096) {
|
if (data != null && data.length != 4096) {
|
||||||
data = new char[4096];
|
data = new char[4096];
|
||||||
Arrays.fill(data, (char) 1);
|
Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR);
|
||||||
}
|
}
|
||||||
if (data == null || data == FaweCache.IMP.EMPTY_CHAR_4096) {
|
if (data == null || data == FaweCache.INSTANCE.EMPTY_CHAR_4096) {
|
||||||
data = new char[4096];
|
data = new char[4096];
|
||||||
Arrays.fill(data, (char) 1);
|
Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR);
|
||||||
}
|
}
|
||||||
DelegateSemaphore lock = PaperweightPlatformAdapter.applyLock(section);
|
DelegateSemaphore lock = PaperweightPlatformAdapter.applyLock(section);
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
@ -874,13 +880,12 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
for (int i = 0; i < 4096; i++) {
|
for (int i = 0; i < 4096; i++) {
|
||||||
char paletteVal = data[i];
|
char paletteVal = data[i];
|
||||||
char ordinal = adapter.ibdIDToOrdinal(paletteVal);
|
char ordinal = adapter.ibdIDToOrdinal(paletteVal);
|
||||||
// Don't read "empty".
|
data[i] = ordinal;
|
||||||
data[i] = ordinal == 0 ? 1 : ordinal;
|
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
char[] paletteToOrdinal = FaweCache.IMP.PALETTE_TO_BLOCK_CHAR.get();
|
char[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK_CHAR.get();
|
||||||
try {
|
try {
|
||||||
if (num_palette != 1) {
|
if (num_palette != 1) {
|
||||||
for (int i = 0; i < num_palette; i++) {
|
for (int i = 0; i < num_palette; i++) {
|
||||||
@ -894,18 +899,10 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
val = ordinal(palette.valueFor(i), adapter);
|
val = ordinal(palette.valueFor(i), adapter);
|
||||||
paletteToOrdinal[i] = val;
|
paletteToOrdinal[i] = val;
|
||||||
}
|
}
|
||||||
// Don't read "empty".
|
|
||||||
if (val == 0) {
|
|
||||||
val = 1;
|
|
||||||
}
|
|
||||||
data[i] = val;
|
data[i] = val;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
char ordinal = ordinal(palette.valueFor(0), adapter);
|
char ordinal = ordinal(palette.valueFor(0), adapter);
|
||||||
// Don't read "empty".
|
|
||||||
if (ordinal == 0) {
|
|
||||||
ordinal = 1;
|
|
||||||
}
|
|
||||||
Arrays.fill(data, ordinal);
|
Arrays.fill(data, ordinal);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@ -925,7 +922,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
|
|
||||||
private char ordinal(net.minecraft.world.level.block.state.BlockState ibd, PaperweightFaweAdapter adapter) {
|
private char ordinal(net.minecraft.world.level.block.state.BlockState ibd, PaperweightFaweAdapter adapter) {
|
||||||
if (ibd == null) {
|
if (ibd == null) {
|
||||||
return BlockTypes.AIR.getDefaultState().getOrdinalChar();
|
return BlockTypesCache.ReservedIDs.AIR;
|
||||||
} else {
|
} else {
|
||||||
return adapter.adaptToChar(ibd);
|
return adapter.adaptToChar(ibd);
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
private static final long fieldLockOffset;
|
private static final long fieldLockOffset;
|
||||||
|
|
||||||
private static final Field fieldGameEventDispatcherSections;
|
private static final Field fieldGameEventDispatcherSections;
|
||||||
private static final MethodHandle methodremoveTickingBlockEntity;
|
private static final MethodHandle methodremoveBlockEntityTicker;
|
||||||
|
|
||||||
private static final Field fieldRemove;
|
private static final Field fieldRemove;
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
), BlockPos.class
|
), BlockPos.class
|
||||||
);
|
);
|
||||||
removeBlockEntityTicker.setAccessible(true);
|
removeBlockEntityTicker.setAccessible(true);
|
||||||
methodremoveTickingBlockEntity = MethodHandles.lookup().unreflect(removeBlockEntityTicker);
|
methodremoveBlockEntityTicker = MethodHandles.lookup().unreflect(removeBlockEntityTicker);
|
||||||
|
|
||||||
fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "p"));
|
fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "p"));
|
||||||
fieldRemove.setAccessible(true);
|
fieldRemove.setAccessible(true);
|
||||||
@ -215,7 +215,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TaskManager.IMP.sync(() -> serverLevel.getChunk(chunkX, chunkZ));
|
return TaskManager.taskManager().sync(() -> serverLevel.getChunk(chunkX, chunkZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChunkHolder getPlayerChunk(ServerLevel nmsWorld, final int chunkX, final int chunkZ) {
|
public static ChunkHolder getPlayerChunk(ServerLevel nmsWorld, final int chunkX, final int chunkZ) {
|
||||||
@ -247,7 +247,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LevelChunk levelChunk = optional.get();
|
LevelChunk levelChunk = optional.get();
|
||||||
TaskManager.IMP.task(() -> {
|
TaskManager.taskManager().task(() -> {
|
||||||
ClientboundLevelChunkPacket chunkPacket = new ClientboundLevelChunkPacket(levelChunk);
|
ClientboundLevelChunkPacket chunkPacket = new ClientboundLevelChunkPacket(levelChunk);
|
||||||
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(chunkPacket));
|
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(chunkPacket));
|
||||||
if (lighting) {
|
if (lighting) {
|
||||||
@ -283,10 +283,10 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
if (set == null) {
|
if (set == null) {
|
||||||
return newChunkSection(layer);
|
return newChunkSection(layer);
|
||||||
}
|
}
|
||||||
final int[] blockToPalette = FaweCache.IMP.BLOCK_TO_PALETTE.get();
|
final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get();
|
||||||
final int[] paletteToBlock = FaweCache.IMP.PALETTE_TO_BLOCK.get();
|
final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get();
|
||||||
final long[] blockStates = FaweCache.IMP.BLOCK_STATES.get();
|
final long[] blockStates = FaweCache.INSTANCE.BLOCK_STATES.get();
|
||||||
final int[] blocksCopy = FaweCache.IMP.SECTION_BLOCKS.get();
|
final int[] blocksCopy = FaweCache.INSTANCE.SECTION_BLOCKS.get();
|
||||||
try {
|
try {
|
||||||
int[] num_palette_buffer = new int[1];
|
int[] num_palette_buffer = new int[1];
|
||||||
Map<BlockVector3, Integer> ticking_blocks = new HashMap<>();
|
Map<BlockVector3, Integer> ticking_blocks = new HashMap<>();
|
||||||
@ -303,7 +303,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
int num_palette = num_palette_buffer[0];
|
int num_palette = num_palette_buffer[0];
|
||||||
// BlockStates
|
// BlockStates
|
||||||
int bitsPerEntry = MathMan.log2nlz(num_palette - 1);
|
int bitsPerEntry = MathMan.log2nlz(num_palette - 1);
|
||||||
if (Settings.IMP.PROTOCOL_SUPPORT_FIX || num_palette != 1) {
|
if (Settings.settings().PROTOCOL_SUPPORT_FIX || num_palette != 1) {
|
||||||
bitsPerEntry = Math.max(bitsPerEntry, 4); // Protocol support breaks <4 bits per entry
|
bitsPerEntry = Math.max(bitsPerEntry, 4); // Protocol support breaks <4 bits per entry
|
||||||
} else {
|
} else {
|
||||||
bitsPerEntry = Math.max(bitsPerEntry, 1); // For some reason minecraft needs 4096 bits to store 0 entries
|
bitsPerEntry = Math.max(bitsPerEntry, 1); // For some reason minecraft needs 4096 bits to store 0 entries
|
||||||
@ -440,7 +440,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
|||||||
fieldRemove.set(beacon, true);
|
fieldRemove.set(beacon, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
methodremoveTickingBlockEntity.invoke(levelChunk, beacon.getBlockPos());
|
methodremoveBlockEntityTicker.invoke(levelChunk, beacon.getBlockPos());
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
throwable.printStackTrace();
|
throwable.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ public class PaperweightStarlightRelighter implements Relighter {
|
|||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
coords.add(new ChunkPos(iterator.nextLong()));
|
coords.add(new ChunkPos(iterator.nextLong()));
|
||||||
}
|
}
|
||||||
TaskManager.IMP.task(() -> {
|
TaskManager.taskManager().task(() -> {
|
||||||
// trigger chunk load and apply ticket on main thread
|
// trigger chunk load and apply ticket on main thread
|
||||||
List<CompletableFuture<?>> futures = new ArrayList<>();
|
List<CompletableFuture<?>> futures = new ArrayList<>();
|
||||||
for (ChunkPos pos : coords) {
|
for (ChunkPos pos : coords) {
|
||||||
@ -153,9 +153,9 @@ public class PaperweightStarlightRelighter implements Relighter {
|
|||||||
LOGGER.warn("Processed {} chunks instead of {}", i, coords.size());
|
LOGGER.warn("Processed {} chunks instead of {}", i, coords.size());
|
||||||
}
|
}
|
||||||
// post process chunks on main thread
|
// post process chunks on main thread
|
||||||
TaskManager.IMP.task(() -> postProcessChunks(coords));
|
TaskManager.taskManager().task(() -> postProcessChunks(coords));
|
||||||
// call callback on our own threads
|
// call callback on our own threads
|
||||||
TaskManager.IMP.async(andThen);
|
TaskManager.taskManager().async(andThen);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -184,7 +184,7 @@ public class PaperweightStarlightRelighter implements Relighter {
|
|||||||
* Also, if chunk packets are sent delayed, we need to do that here
|
* Also, if chunk packets are sent delayed, we need to do that here
|
||||||
*/
|
*/
|
||||||
private void postProcessChunks(Set<ChunkPos> coords) {
|
private void postProcessChunks(Set<ChunkPos> coords) {
|
||||||
boolean delay = Settings.IMP.LIGHTING.DELAY_PACKET_SENDING;
|
boolean delay = Settings.settings().LIGHTING.DELAY_PACKET_SENDING;
|
||||||
for (ChunkPos pos : coords) {
|
for (ChunkPos pos : coords) {
|
||||||
int x = pos.x;
|
int x = pos.x;
|
||||||
int z = pos.z;
|
int z = pos.z;
|
||||||
|
@ -66,8 +66,8 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag {
|
|||||||
|
|
||||||
public double asDouble(String key) {
|
public double asDouble(String key) {
|
||||||
net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key);
|
net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key);
|
||||||
if (tag instanceof NumericTag) {
|
if (tag instanceof NumericTag numTag) {
|
||||||
return ((NumericTag) tag).getAsDouble();
|
return numTag.getAsDouble();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -86,20 +86,19 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag {
|
|||||||
|
|
||||||
public int asInt(String key) {
|
public int asInt(String key) {
|
||||||
net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key);
|
net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key);
|
||||||
if (tag instanceof NumericTag) {
|
if (tag instanceof NumericTag numTag) {
|
||||||
return ((NumericTag) tag).getAsInt();
|
return numTag.getAsInt();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Tag> getList(String key) {
|
public List<Tag> getList(String key) {
|
||||||
net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key);
|
net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key);
|
||||||
if (tag instanceof net.minecraft.nbt.ListTag) {
|
if (tag instanceof net.minecraft.nbt.ListTag nbtList) {
|
||||||
ArrayList<Tag> list = new ArrayList<>();
|
ArrayList<Tag> list = new ArrayList<>();
|
||||||
net.minecraft.nbt.ListTag nbtList = (net.minecraft.nbt.ListTag) tag;
|
|
||||||
for (net.minecraft.nbt.Tag elem : nbtList) {
|
for (net.minecraft.nbt.Tag elem : nbtList) {
|
||||||
if (elem instanceof net.minecraft.nbt.CompoundTag) {
|
if (elem instanceof net.minecraft.nbt.CompoundTag compoundTag) {
|
||||||
list.add(new PaperweightLazyCompoundTag((net.minecraft.nbt.CompoundTag) elem));
|
list.add(new PaperweightLazyCompoundTag(compoundTag));
|
||||||
} else {
|
} else {
|
||||||
list.add(WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(elem));
|
list.add(WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(elem));
|
||||||
}
|
}
|
||||||
@ -137,8 +136,8 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag {
|
|||||||
|
|
||||||
public long asLong(String key) {
|
public long asLong(String key) {
|
||||||
net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key);
|
net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key);
|
||||||
if (tag instanceof NumericTag) {
|
if (tag instanceof NumericTag numTag) {
|
||||||
return ((NumericTag) tag).getAsLong();
|
return numTag.getAsLong();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -90,13 +90,13 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
|
|
||||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||||
|
|
||||||
private static final Field serverWorldsField;
|
private static final Field worldsField;
|
||||||
private static final Field worldPaperConfigField;
|
private static final Field paperConfigField;
|
||||||
private static final Field flatBedrockField;
|
private static final Field generateFlatBedrockField;
|
||||||
private static final Field generatorSettingFlatField;
|
private static final Field generatorSettingFlatField;
|
||||||
private static final Field generatorSettingBaseSupplierField;
|
private static final Field generatorSettingBaseSupplierField;
|
||||||
private static final Field delegateField;
|
private static final Field delegateField;
|
||||||
private static final Field chunkProviderField;
|
private static final Field chunkSourceField;
|
||||||
|
|
||||||
//list of chunk stati in correct order without FULL
|
//list of chunk stati in correct order without FULL
|
||||||
private static final Map<ChunkStatus, Concurrency> chunkStati = new LinkedHashMap<>();
|
private static final Map<ChunkStatus, Concurrency> chunkStati = new LinkedHashMap<>();
|
||||||
@ -125,8 +125,8 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
chunkStati.put(ChunkStatus.HEIGHTMAPS, Concurrency.FULL); // heightmaps: radius 0
|
chunkStati.put(ChunkStatus.HEIGHTMAPS, Concurrency.FULL); // heightmaps: radius 0
|
||||||
|
|
||||||
try {
|
try {
|
||||||
serverWorldsField = CraftServer.class.getDeclaredField("worlds");
|
worldsField = CraftServer.class.getDeclaredField("worlds");
|
||||||
serverWorldsField.setAccessible(true);
|
worldsField.setAccessible(true);
|
||||||
|
|
||||||
Field tmpPaperConfigField;
|
Field tmpPaperConfigField;
|
||||||
Field tmpFlatBedrockField;
|
Field tmpFlatBedrockField;
|
||||||
@ -140,8 +140,8 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
tmpPaperConfigField = null;
|
tmpPaperConfigField = null;
|
||||||
tmpFlatBedrockField = null;
|
tmpFlatBedrockField = null;
|
||||||
}
|
}
|
||||||
worldPaperConfigField = tmpPaperConfigField;
|
paperConfigField = tmpPaperConfigField;
|
||||||
flatBedrockField = tmpFlatBedrockField;
|
generateFlatBedrockField = tmpFlatBedrockField;
|
||||||
|
|
||||||
generatorSettingBaseSupplierField = NoiseBasedChunkGenerator.class.getDeclaredField(Refraction.pickName(
|
generatorSettingBaseSupplierField = NoiseBasedChunkGenerator.class.getDeclaredField(Refraction.pickName(
|
||||||
"settings", "g"));
|
"settings", "g"));
|
||||||
@ -153,8 +153,8 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
delegateField = CustomChunkGenerator.class.getDeclaredField("delegate");
|
delegateField = CustomChunkGenerator.class.getDeclaredField("delegate");
|
||||||
delegateField.setAccessible(true);
|
delegateField.setAccessible(true);
|
||||||
|
|
||||||
chunkProviderField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "C"));
|
chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "C"));
|
||||||
chunkProviderField.setAccessible(true);
|
chunkSourceField.setAccessible(true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@ -187,9 +187,9 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
}
|
}
|
||||||
|
|
||||||
//flat bedrock? (only on paper)
|
//flat bedrock? (only on paper)
|
||||||
if (worldPaperConfigField != null) {
|
if (paperConfigField != null) {
|
||||||
try {
|
try {
|
||||||
generateFlatBedrock = flatBedrockField.getBoolean(worldPaperConfigField.get(originalServerWorld));
|
generateFlatBedrock = generateFlatBedrockField.getBoolean(paperConfigField.get(originalServerWorld));
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,7 +210,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
org.bukkit.generator.ChunkGenerator generator = originalBukkitWorld.getGenerator();
|
org.bukkit.generator.ChunkGenerator generator = originalBukkitWorld.getGenerator();
|
||||||
LevelStorageSource levelStorageSource = LevelStorageSource.createDefault(tempDir);
|
LevelStorageSource levelStorageSource = LevelStorageSource.createDefault(tempDir);
|
||||||
ResourceKey<LevelStem> levelStemResourceKey = getWorldDimKey(environment);
|
ResourceKey<LevelStem> levelStemResourceKey = getWorldDimKey(environment);
|
||||||
session = levelStorageSource.createAccess("worldeditregentempworld", levelStemResourceKey);
|
session = levelStorageSource.createAccess("faweregentempworld", levelStemResourceKey);
|
||||||
PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData;
|
PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData;
|
||||||
|
|
||||||
MinecraftServer server = originalServerWorld.getCraftServer().getServer();
|
MinecraftServer server = originalServerWorld.getCraftServer().getServer();
|
||||||
@ -221,7 +221,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
? PaperweightAdapter.replaceSeed(originalServerWorld, seed, originalOpts)
|
? PaperweightAdapter.replaceSeed(originalServerWorld, seed, originalOpts)
|
||||||
: originalOpts;
|
: originalOpts;
|
||||||
LevelSettings newWorldSettings = new LevelSettings(
|
LevelSettings newWorldSettings = new LevelSettings(
|
||||||
"worldeditregentempworld",
|
"faweregentempworld",
|
||||||
originalWorldData.settings.gameType(),
|
originalWorldData.settings.gameType(),
|
||||||
originalWorldData.settings.hardcore(),
|
originalWorldData.settings.hardcore(),
|
||||||
originalWorldData.settings.difficulty(),
|
originalWorldData.settings.difficulty(),
|
||||||
@ -232,7 +232,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, Lifecycle.stable());
|
PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, Lifecycle.stable());
|
||||||
|
|
||||||
//init world
|
//init world
|
||||||
freshWorld = Fawe.get().getQueueHandler().sync((Supplier<ServerLevel>) () -> new ServerLevel(
|
freshWorld = Fawe.instance().getQueueHandler().sync((Supplier<ServerLevel>) () -> new ServerLevel(
|
||||||
server,
|
server,
|
||||||
server.executor,
|
server.executor,
|
||||||
session,
|
session,
|
||||||
@ -270,8 +270,8 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
freshWorld.noSave = true;
|
freshWorld.noSave = true;
|
||||||
removeWorldFromWorldsMap();
|
removeWorldFromWorldsMap();
|
||||||
newWorldData.checkName(originalServerWorld.serverLevelData.getLevelName()); //rename to original world name
|
newWorldData.checkName(originalServerWorld.serverLevelData.getLevelName()); //rename to original world name
|
||||||
if (worldPaperConfigField != null) {
|
if (paperConfigField != null) {
|
||||||
worldPaperConfigField.set(freshWorld, originalServerWorld.paperConfig);
|
paperConfigField.set(freshWorld, originalServerWorld.paperConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
//generator
|
//generator
|
||||||
@ -319,7 +319,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ReflectionUtils.unsafeSet(chunkProviderField, freshWorld, freshChunkProvider);
|
ReflectionUtils.unsafeSet(chunkSourceField, freshWorld, freshChunkProvider);
|
||||||
//let's start then
|
//let's start then
|
||||||
structureManager = server.getStructureManager();
|
structureManager = server.getStructureManager();
|
||||||
threadedLevelLightEngine = freshChunkProvider.getLightEngine();
|
threadedLevelLightEngine = freshChunkProvider.getLightEngine();
|
||||||
@ -336,7 +336,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
|
|
||||||
//shutdown chunk provider
|
//shutdown chunk provider
|
||||||
try {
|
try {
|
||||||
Fawe.get().getQueueHandler().sync(() -> {
|
Fawe.instance().getQueueHandler().sync(() -> {
|
||||||
try {
|
try {
|
||||||
freshChunkProvider.close(false);
|
freshChunkProvider.close(false);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -348,7 +348,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
|
|
||||||
//remove world from server
|
//remove world from server
|
||||||
try {
|
try {
|
||||||
Fawe.get().getQueueHandler().sync(this::removeWorldFromWorldsMap);
|
Fawe.instance().getQueueHandler().sync(this::removeWorldFromWorldsMap);
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,7 +388,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
@Override
|
@Override
|
||||||
protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blockPopulator) {
|
protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blockPopulator) {
|
||||||
// BlockPopulator#populate has to be called synchronously for TileEntity access
|
// BlockPopulator#populate has to be called synchronously for TileEntity access
|
||||||
TaskManager.IMP.task(() -> blockPopulator.populate(freshWorld.getWorld(), random, levelChunk.getBukkitChunk()));
|
TaskManager.taskManager().task(() -> blockPopulator.populate(freshWorld.getWorld(), random, levelChunk.getBukkitChunk()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -403,10 +403,10 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
|
|
||||||
//util
|
//util
|
||||||
private void removeWorldFromWorldsMap() {
|
private void removeWorldFromWorldsMap() {
|
||||||
Fawe.get().getQueueHandler().sync(() -> {
|
Fawe.instance().getQueueHandler().sync(() -> {
|
||||||
try {
|
try {
|
||||||
Map<String, org.bukkit.World> map = (Map<String, org.bukkit.World>) serverWorldsField.get(Bukkit.getServer());
|
Map<String, org.bukkit.World> map = (Map<String, org.bukkit.World>) worldsField.get(Bukkit.getServer());
|
||||||
map.remove("worldeditregentempworld");
|
map.remove("faweregentempworld");
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@ -414,15 +414,11 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ResourceKey<LevelStem> getWorldDimKey(org.bukkit.World.Environment env) {
|
private ResourceKey<LevelStem> getWorldDimKey(org.bukkit.World.Environment env) {
|
||||||
switch (env) {
|
return switch (env) {
|
||||||
case NETHER:
|
case NETHER -> LevelStem.NETHER;
|
||||||
return LevelStem.NETHER;
|
case THE_END -> LevelStem.END;
|
||||||
case THE_END:
|
default -> LevelStem.OVERWORLD;
|
||||||
return LevelStem.END;
|
};
|
||||||
case NORMAL:
|
|
||||||
default:
|
|
||||||
return LevelStem.OVERWORLD;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BiomeSource fastOverworldBiomeSource(BiomeSource biomeSource) throws Exception {
|
private BiomeSource fastOverworldBiomeSource(BiomeSource biomeSource) throws Exception {
|
||||||
|
17
worldedit-bukkit/adapters/adapter-1_18/build.gradle.kts
Normale Datei
17
worldedit-bukkit/adapters/adapter-1_18/build.gradle.kts
Normale Datei
@ -0,0 +1,17 @@
|
|||||||
|
plugins {
|
||||||
|
java
|
||||||
|
}
|
||||||
|
|
||||||
|
applyPaperweightAdapterConfiguration()
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
name = "PaperMC"
|
||||||
|
url = uri("https://papermc.io/repo/repository/maven-public/")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
paperDevBundle("1.18.1-R0.1-20211221.093324-19")
|
||||||
|
compileOnly(libs.paperlib)
|
||||||
|
}
|
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* 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.bukkit.adapter.ext.fawe.v1_18_R1;
|
||||||
|
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import net.minecraft.network.chat.ChatType;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.protocol.game.ServerboundClientInformationPacket;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.stats.Stat;
|
||||||
|
import net.minecraft.world.MenuProvider;
|
||||||
|
import net.minecraft.world.damagesource.DamageSource;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.level.block.entity.SignBlockEntity;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||||
|
|
||||||
|
import java.util.OptionalInt;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
class PaperweightFakePlayer extends ServerPlayer {
|
||||||
|
|
||||||
|
private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(
|
||||||
|
UUID.nameUUIDFromBytes("worldedit".getBytes()),
|
||||||
|
"[WorldEdit]"
|
||||||
|
);
|
||||||
|
private static final Vec3 ORIGIN = new Vec3(0.0D, 0.0D, 0.0D);
|
||||||
|
|
||||||
|
PaperweightFakePlayer(ServerLevel world) {
|
||||||
|
super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vec3 position() {
|
||||||
|
return ORIGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void die(DamageSource damagesource) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity changeDimension(ServerLevel worldserver, TeleportCause cause) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OptionalInt openMenu(MenuProvider factory) {
|
||||||
|
return OptionalInt.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateOptions(ServerboundClientInformationPacket packet) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayClientMessage(Component message, boolean actionBar) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(Component message, ChatType type, UUID sender) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void awardStat(Stat<?> stat, int amount) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void awardStat(Stat<?> stat) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInvulnerableTo(DamageSource damageSource) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void openTextEdit(SignBlockEntity sign) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
* 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.bukkit.adapter.ext.fawe.v1_18_R1;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
|
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
||||||
|
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
|
||||||
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
|
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.server.level.ChunkHolder;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.block.data.CraftBlockData;
|
||||||
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class PaperweightWorldNativeAccess implements
|
||||||
|
WorldNativeAccess<LevelChunk, net.minecraft.world.level.block.state.BlockState, BlockPos> {
|
||||||
|
|
||||||
|
private static final int UPDATE = 1;
|
||||||
|
private static final int NOTIFY = 2;
|
||||||
|
|
||||||
|
private final PaperweightAdapter adapter;
|
||||||
|
private final WeakReference<ServerLevel> world;
|
||||||
|
private SideEffectSet sideEffectSet;
|
||||||
|
|
||||||
|
public PaperweightWorldNativeAccess(PaperweightAdapter adapter, WeakReference<ServerLevel> world) {
|
||||||
|
this.adapter = adapter;
|
||||||
|
this.world = world;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ServerLevel getWorld() {
|
||||||
|
return Objects.requireNonNull(world.get(), "The reference to the world was lost");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) {
|
||||||
|
this.sideEffectSet = sideEffectSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LevelChunk getChunk(int x, int z) {
|
||||||
|
return getWorld().getChunk(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public net.minecraft.world.level.block.state.BlockState toNative(BlockState state) {
|
||||||
|
int stateId = BlockStateIdAccess.getBlockStateId(state);
|
||||||
|
return BlockStateIdAccess.isValidInternalId(stateId)
|
||||||
|
? Block.stateById(stateId)
|
||||||
|
: ((CraftBlockData) BukkitAdapter.adapt(state)).getState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public net.minecraft.world.level.block.state.BlockState getBlockState(LevelChunk chunk, BlockPos position) {
|
||||||
|
return chunk.getBlockState(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public net.minecraft.world.level.block.state.BlockState setBlockState(
|
||||||
|
LevelChunk chunk,
|
||||||
|
BlockPos position,
|
||||||
|
net.minecraft.world.level.block.state.BlockState state
|
||||||
|
) {
|
||||||
|
return chunk.setBlockState(position, state, false, this.sideEffectSet.shouldApply(SideEffect.UPDATE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition(
|
||||||
|
net.minecraft.world.level.block.state.BlockState block,
|
||||||
|
BlockPos position
|
||||||
|
) {
|
||||||
|
return Block.updateFromNeighbourShapes(block, getWorld(), position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockPos getPosition(int x, int y, int z) {
|
||||||
|
return new BlockPos(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLightingForBlock(BlockPos position) {
|
||||||
|
getWorld().getChunkSource().getLightEngine().checkBlock(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateTileEntity(final BlockPos position, final CompoundBinaryTag tag) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyBlockUpdate(
|
||||||
|
LevelChunk chunk,
|
||||||
|
BlockPos position,
|
||||||
|
net.minecraft.world.level.block.state.BlockState oldState,
|
||||||
|
net.minecraft.world.level.block.state.BlockState newState
|
||||||
|
) {
|
||||||
|
if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) {
|
||||||
|
getWorld().sendBlockUpdated(position, oldState, newState, UPDATE | NOTIFY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChunkTicking(LevelChunk chunk) {
|
||||||
|
return chunk.getFullStatus().isOrAfter(ChunkHolder.FullChunkStatus.TICKING);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void markBlockChanged(LevelChunk chunk, BlockPos position) {
|
||||||
|
if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) {
|
||||||
|
getWorld().getChunkSource().blockChanged(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyNeighbors(
|
||||||
|
BlockPos pos,
|
||||||
|
net.minecraft.world.level.block.state.BlockState oldState,
|
||||||
|
net.minecraft.world.level.block.state.BlockState newState
|
||||||
|
) {
|
||||||
|
ServerLevel world = getWorld();
|
||||||
|
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
|
||||||
|
world.updateNeighborsAt(pos, oldState.getBlock());
|
||||||
|
} else {
|
||||||
|
// When we don't want events, manually run the physics without them.
|
||||||
|
Block block = oldState.getBlock();
|
||||||
|
fireNeighborChanged(pos, world, block, pos.west());
|
||||||
|
fireNeighborChanged(pos, world, block, pos.east());
|
||||||
|
fireNeighborChanged(pos, world, block, pos.below());
|
||||||
|
fireNeighborChanged(pos, world, block, pos.above());
|
||||||
|
fireNeighborChanged(pos, world, block, pos.north());
|
||||||
|
fireNeighborChanged(pos, world, block, pos.south());
|
||||||
|
}
|
||||||
|
if (newState.hasAnalogOutputSignal()) {
|
||||||
|
world.updateNeighbourForOutputSignal(pos, newState.getBlock());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fireNeighborChanged(BlockPos pos, ServerLevel world, Block block, BlockPos neighborPos) {
|
||||||
|
world.getBlockState(neighborPos).neighborChanged(world, neighborPos, block, pos, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNeighbors(
|
||||||
|
BlockPos pos,
|
||||||
|
net.minecraft.world.level.block.state.BlockState oldState,
|
||||||
|
net.minecraft.world.level.block.state.BlockState newState,
|
||||||
|
int recursionLimit
|
||||||
|
) {
|
||||||
|
ServerLevel world = getWorld();
|
||||||
|
// a == updateNeighbors
|
||||||
|
// b == updateDiagonalNeighbors
|
||||||
|
oldState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit);
|
||||||
|
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
|
||||||
|
CraftWorld craftWorld = world.getWorld();
|
||||||
|
BlockPhysicsEvent event = new BlockPhysicsEvent(
|
||||||
|
craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()),
|
||||||
|
CraftBlockData.fromData(newState)
|
||||||
|
);
|
||||||
|
world.getCraftServer().getPluginManager().callEvent(event);
|
||||||
|
if (event.isCancelled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newState.updateNeighbourShapes(world, pos, NOTIFY, recursionLimit);
|
||||||
|
newState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBlockStateChange(
|
||||||
|
BlockPos pos,
|
||||||
|
net.minecraft.world.level.block.state.BlockState oldState,
|
||||||
|
net.minecraft.world.level.block.state.BlockState newState
|
||||||
|
) {
|
||||||
|
getWorld().onBlockStateChange(pos, oldState, newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,189 @@
|
|||||||
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1;
|
||||||
|
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.util.ReflectionUtil;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1.nbt.PaperweightLazyCompoundTag;
|
||||||
|
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.level.EmptyBlockGetter;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.material.Material;
|
||||||
|
import net.minecraft.world.level.material.PushReaction;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.block.data.CraftBlockData;
|
||||||
|
|
||||||
|
public class PaperweightBlockMaterial implements BlockMaterial {
|
||||||
|
|
||||||
|
private final Block block;
|
||||||
|
private final BlockState blockState;
|
||||||
|
private final Material material;
|
||||||
|
private final boolean isTranslucent;
|
||||||
|
private final CraftBlockData craftBlockData;
|
||||||
|
private final org.bukkit.Material craftMaterial;
|
||||||
|
private final int opacity;
|
||||||
|
private final CompoundTag tile;
|
||||||
|
|
||||||
|
public PaperweightBlockMaterial(Block block) {
|
||||||
|
this(block, block.defaultBlockState());
|
||||||
|
}
|
||||||
|
|
||||||
|
public PaperweightBlockMaterial(Block block, BlockState blockState) {
|
||||||
|
this.block = block;
|
||||||
|
this.blockState = blockState;
|
||||||
|
this.material = blockState.getMaterial();
|
||||||
|
this.craftBlockData = CraftBlockData.fromData(blockState);
|
||||||
|
this.craftMaterial = craftBlockData.getMaterial();
|
||||||
|
BlockBehaviour.Properties blockInfo = ReflectionUtil.getField(BlockBehaviour.class, block, Refraction.pickName(
|
||||||
|
"properties", "aP"));
|
||||||
|
this.isTranslucent = !(boolean) ReflectionUtil.getField(BlockBehaviour.Properties.class, blockInfo,
|
||||||
|
Refraction.pickName("canOcclude", "n")
|
||||||
|
);
|
||||||
|
opacity = blockState.getLightBlock(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
|
||||||
|
BlockEntity tileEntity = !(block instanceof EntityBlock) ? null : ((EntityBlock) block).newBlockEntity(
|
||||||
|
BlockPos.ZERO,
|
||||||
|
blockState
|
||||||
|
);
|
||||||
|
tile = tileEntity == null
|
||||||
|
? null
|
||||||
|
: new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Block getBlock() {
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockState getState() {
|
||||||
|
return blockState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CraftBlockData getCraftBlockData() {
|
||||||
|
return craftBlockData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Material getMaterial() {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAir() {
|
||||||
|
return blockState.isAir();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFullCube() {
|
||||||
|
return craftMaterial.isOccluding();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOpaque() {
|
||||||
|
return material.isSolidBlocking();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPowerSource() {
|
||||||
|
return blockState.isSignalSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLiquid() {
|
||||||
|
return material.isLiquid();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSolid() {
|
||||||
|
return material.isSolid();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getHardness() {
|
||||||
|
return craftBlockData.getState().destroySpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getResistance() {
|
||||||
|
return block.getExplosionResistance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getSlipperiness() {
|
||||||
|
return block.getFriction();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLightValue() {
|
||||||
|
return blockState.getLightEmission();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLightOpacity() {
|
||||||
|
return opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFragileWhenPushed() {
|
||||||
|
return material.getPushReaction() == PushReaction.DESTROY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUnpushable() {
|
||||||
|
return material.getPushReaction() == PushReaction.BLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTicksRandomly() {
|
||||||
|
return block.isRandomlyTicking(blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMovementBlocker() {
|
||||||
|
return material.isSolid();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBurnable() {
|
||||||
|
return material.isFlammable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isToolRequired() {
|
||||||
|
// Removed in 1.16.1, this is not present in higher versions
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReplacedDuringPlacement() {
|
||||||
|
return material.isReplaceable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTranslucent() {
|
||||||
|
return isTranslucent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasContainer() {
|
||||||
|
return block instanceof EntityBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTile() {
|
||||||
|
return block instanceof EntityBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundTag getDefaultTile() {
|
||||||
|
return tile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMapColor() {
|
||||||
|
// rgb field
|
||||||
|
return material.getColor().col;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,689 @@
|
|||||||
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1;
|
||||||
|
|
||||||
|
import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter;
|
||||||
|
import com.fastasyncworldedit.bukkit.adapter.IDelegateBukkitImplAdapter;
|
||||||
|
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
||||||
|
import com.fastasyncworldedit.core.FaweCache;
|
||||||
|
import com.fastasyncworldedit.core.entity.LazyBaseEntity;
|
||||||
|
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
||||||
|
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||||
|
import com.fastasyncworldedit.core.queue.implementation.packet.ChunkPacket;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.sk89q.jnbt.Tag;
|
||||||
|
import com.sk89q.worldedit.EditSession;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||||
|
import com.sk89q.worldedit.blocks.TileEntityBlock;
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R1.PaperweightAdapter;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1.nbt.PaperweightLazyCompoundTag;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1.regen.PaperweightRegen;
|
||||||
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
||||||
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
|
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.registry.state.BooleanProperty;
|
||||||
|
import com.sk89q.worldedit.registry.state.DirectionalProperty;
|
||||||
|
import com.sk89q.worldedit.registry.state.EnumProperty;
|
||||||
|
import com.sk89q.worldedit.registry.state.IntegerProperty;
|
||||||
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
|
import com.sk89q.worldedit.util.Direction;
|
||||||
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
|
import com.sk89q.worldedit.util.TreeGenerator;
|
||||||
|
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||||
|
import com.sk89q.worldedit.util.nbt.BinaryTag;
|
||||||
|
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
||||||
|
import com.sk89q.worldedit.util.nbt.StringBinaryTag;
|
||||||
|
import com.sk89q.worldedit.world.RegenOptions;
|
||||||
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
|
import com.sk89q.worldedit.world.entity.EntityType;
|
||||||
|
import com.sk89q.worldedit.world.item.ItemType;
|
||||||
|
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.core.WritableRegistry;
|
||||||
|
import net.minecraft.nbt.IntTag;
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.level.ChunkHolder;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.util.StringRepresentable;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.TreeType;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.CraftChunk;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.CraftServer;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.block.CraftBlock;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.block.CraftBlockState;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.block.data.CraftBlockData;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftEntity;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftPlayer;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.util.CraftNamespacedKey;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.OptionalInt;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements
|
||||||
|
IDelegateBukkitImplAdapter<net.minecraft.nbt.Tag> {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||||
|
|
||||||
|
private final PaperweightAdapter parent;
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Code that may break between versions of Minecraft
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
private final PaperweightMapChunkUtil mapUtil = new PaperweightMapChunkUtil();
|
||||||
|
private char[] ibdToStateOrdinal = null;
|
||||||
|
private int[] ordinalToIbdID = null;
|
||||||
|
private boolean initialised = false;
|
||||||
|
private Map<String, List<Property<?>>> allBlockProperties = null;
|
||||||
|
|
||||||
|
public PaperweightFaweAdapter() throws NoSuchFieldException, NoSuchMethodException {
|
||||||
|
this.parent = new PaperweightAdapter();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static String getEntityId(Entity entity) {
|
||||||
|
ResourceLocation resourceLocation = net.minecraft.world.entity.EntityType.getKey(entity.getType());
|
||||||
|
return resourceLocation == null ? null : resourceLocation.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) {
|
||||||
|
entity.save(compoundTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BukkitImplAdapter<net.minecraft.nbt.Tag> getParent() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized boolean init() {
|
||||||
|
if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size
|
||||||
|
ordinalToIbdID = new int[ibdToStateOrdinal.length]; // size
|
||||||
|
for (int i = 0; i < ibdToStateOrdinal.length; i++) {
|
||||||
|
BlockState blockState = BlockTypesCache.states[i];
|
||||||
|
PaperweightBlockMaterial material = (PaperweightBlockMaterial) blockState.getMaterial();
|
||||||
|
int id = Block.BLOCK_STATE_REGISTRY.getId(material.getState());
|
||||||
|
char ordinal = blockState.getOrdinalChar();
|
||||||
|
ibdToStateOrdinal[id] = ordinal;
|
||||||
|
ordinalToIbdID[ordinal] = id;
|
||||||
|
}
|
||||||
|
Map<String, List<Property<?>>> properties = new HashMap<>();
|
||||||
|
try {
|
||||||
|
for (Field field : BlockStateProperties.class.getDeclaredFields()) {
|
||||||
|
Object obj = field.get(null);
|
||||||
|
if (!(obj instanceof net.minecraft.world.level.block.state.properties.Property<?> state)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Property<?> property;
|
||||||
|
if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) {
|
||||||
|
property = new BooleanProperty(
|
||||||
|
state.getName(),
|
||||||
|
(List<Boolean>) ImmutableList.copyOf(state.getPossibleValues())
|
||||||
|
);
|
||||||
|
} else if (state instanceof DirectionProperty) {
|
||||||
|
property = new DirectionalProperty(
|
||||||
|
state.getName(),
|
||||||
|
state
|
||||||
|
.getPossibleValues()
|
||||||
|
.stream()
|
||||||
|
.map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase()))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
);
|
||||||
|
} else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
|
||||||
|
property = new EnumProperty(
|
||||||
|
state.getName(),
|
||||||
|
state
|
||||||
|
.getPossibleValues()
|
||||||
|
.stream()
|
||||||
|
.map(e -> ((StringRepresentable) e).getSerializedName())
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
);
|
||||||
|
} else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) {
|
||||||
|
property = new IntegerProperty(
|
||||||
|
state.getName(),
|
||||||
|
(List<Integer>) ImmutableList.copyOf(state.getPossibleValues())
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("FastAsyncWorldEdit needs an update to support " + state
|
||||||
|
.getClass()
|
||||||
|
.getSimpleName());
|
||||||
|
}
|
||||||
|
properties.compute(property.getName().toLowerCase(Locale.ROOT), (k, v) -> {
|
||||||
|
if (v == null) {
|
||||||
|
v = new ArrayList<>(Collections.singletonList(property));
|
||||||
|
} else {
|
||||||
|
v.add(property);
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
allBlockProperties = ImmutableMap.copyOf(properties);
|
||||||
|
}
|
||||||
|
initialised = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockMaterial getMaterial(BlockType blockType) {
|
||||||
|
Block block = getBlock(blockType);
|
||||||
|
return new PaperweightBlockMaterial(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized BlockMaterial getMaterial(BlockState state) {
|
||||||
|
net.minecraft.world.level.block.state.BlockState blockState = ((CraftBlockData) Bukkit.createBlockData(state.getAsString())).getState();
|
||||||
|
return new PaperweightBlockMaterial(blockState.getBlock(), blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Block getBlock(BlockType blockType) {
|
||||||
|
return Registry.BLOCK.get(new ResourceLocation(blockType.getNamespace(), blockType.getResource()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public BlockState getBlock(Location location) {
|
||||||
|
Preconditions.checkNotNull(location);
|
||||||
|
|
||||||
|
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
|
||||||
|
int x = location.getBlockX();
|
||||||
|
int y = location.getBlockY();
|
||||||
|
int z = location.getBlockZ();
|
||||||
|
final ServerLevel handle = craftWorld.getHandle();
|
||||||
|
LevelChunk chunk = handle.getChunk(x >> 4, z >> 4);
|
||||||
|
final BlockPos blockPos = new BlockPos(x, y, z);
|
||||||
|
final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos);
|
||||||
|
BlockState state = adapt(blockData);
|
||||||
|
if (state == null) {
|
||||||
|
org.bukkit.block.Block bukkitBlock = location.getBlock();
|
||||||
|
state = BukkitAdapter.adapt(bukkitBlock.getBlockData());
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock getFullBlock(final Location location) {
|
||||||
|
Preconditions.checkNotNull(location);
|
||||||
|
|
||||||
|
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
|
||||||
|
int x = location.getBlockX();
|
||||||
|
int y = location.getBlockY();
|
||||||
|
int z = location.getBlockZ();
|
||||||
|
|
||||||
|
final ServerLevel handle = craftWorld.getHandle();
|
||||||
|
LevelChunk chunk = handle.getChunk(x >> 4, z >> 4);
|
||||||
|
final BlockPos blockPos = new BlockPos(x, y, z);
|
||||||
|
final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos);
|
||||||
|
BlockState state = adapt(blockData);
|
||||||
|
if (state == null) {
|
||||||
|
org.bukkit.block.Block bukkitBlock = location.getBlock();
|
||||||
|
state = BukkitAdapter.adapt(bukkitBlock.getBlockData());
|
||||||
|
}
|
||||||
|
if (state.getBlockType().getMaterial().hasContainer()) {
|
||||||
|
|
||||||
|
// Read the NBT data
|
||||||
|
BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK);
|
||||||
|
if (blockEntity != null) {
|
||||||
|
net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId();
|
||||||
|
return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.toBaseBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<SideEffect> getSupportedSideEffects() {
|
||||||
|
return SideEffectSet.defaults().getSideEffectsToApply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setBlock(org.bukkit.Chunk chunk, int x, int y, int z, BlockStateHolder state, boolean update) {
|
||||||
|
CraftChunk craftChunk = (CraftChunk) chunk;
|
||||||
|
LevelChunk levelChunk = craftChunk.getHandle();
|
||||||
|
Level level = levelChunk.getLevel();
|
||||||
|
|
||||||
|
BlockPos blockPos = new BlockPos(x, y, z);
|
||||||
|
net.minecraft.world.level.block.state.BlockState blockState = ((PaperweightBlockMaterial) state.getMaterial()).getState();
|
||||||
|
LevelChunkSection[] levelChunkSections = levelChunk.getSections();
|
||||||
|
int y4 = y >> 4;
|
||||||
|
LevelChunkSection section = levelChunkSections[y4];
|
||||||
|
|
||||||
|
net.minecraft.world.level.block.state.BlockState existing;
|
||||||
|
if (section == null) {
|
||||||
|
existing = ((PaperweightBlockMaterial) BlockTypes.AIR.getDefaultState().getMaterial()).getState();
|
||||||
|
} else {
|
||||||
|
existing = section.getBlockState(x & 15, y & 15, z & 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
levelChunk.removeBlockEntity(blockPos); // Force delete the old tile entity
|
||||||
|
|
||||||
|
CompoundBinaryTag compoundTag = state instanceof BaseBlock ? state.getNbt() : null;
|
||||||
|
if (compoundTag != null || existing instanceof TileEntityBlock) {
|
||||||
|
level.setBlock(blockPos, blockState, 0);
|
||||||
|
// remove tile
|
||||||
|
if (compoundTag != null) {
|
||||||
|
// We will assume that the tile entity was created for us,
|
||||||
|
// though we do not do this on the Forge version
|
||||||
|
BlockEntity blockEntity = level.getBlockEntity(blockPos);
|
||||||
|
if (blockEntity != null) {
|
||||||
|
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) fromNativeBinary(compoundTag);
|
||||||
|
tag.put("x", IntTag.valueOf(x));
|
||||||
|
tag.put("y", IntTag.valueOf(y));
|
||||||
|
tag.put("z", IntTag.valueOf(z));
|
||||||
|
blockEntity.load(tag); // readTagIntoTileEntity - load data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (existing == blockState) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
levelChunk.setBlockState(blockPos, blockState, false);
|
||||||
|
}
|
||||||
|
if (update) {
|
||||||
|
level.getMinecraftWorld().sendBlockUpdated(blockPos, existing, blockState, 0);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) {
|
||||||
|
return new PaperweightFaweWorldNativeAccess(
|
||||||
|
this,
|
||||||
|
new WeakReference<>(((CraftWorld) world).getHandle())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseEntity getEntity(org.bukkit.entity.Entity entity) {
|
||||||
|
Preconditions.checkNotNull(entity);
|
||||||
|
|
||||||
|
CraftEntity craftEntity = ((CraftEntity) entity);
|
||||||
|
Entity mcEntity = craftEntity.getHandle();
|
||||||
|
|
||||||
|
String id = getEntityId(mcEntity);
|
||||||
|
|
||||||
|
if (id != null) {
|
||||||
|
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
|
||||||
|
Supplier<CompoundBinaryTag> saveTag = () -> {
|
||||||
|
final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag();
|
||||||
|
readEntityIntoTag(mcEntity, minecraftTag);
|
||||||
|
//add Id for AbstractChangeSet to work
|
||||||
|
final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag);
|
||||||
|
final Map<String, BinaryTag> tags = new HashMap<>();
|
||||||
|
tag.keySet().forEach(key -> tags.put(key, tag.get(key)));
|
||||||
|
tags.put("Id", StringBinaryTag.of(id));
|
||||||
|
return CompoundBinaryTag.from(tags);
|
||||||
|
};
|
||||||
|
return new LazyBaseEntity(type, saveTag);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getRichBlockName(BlockType blockType) {
|
||||||
|
return parent.getRichBlockName(blockType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getRichItemName(ItemType itemType) {
|
||||||
|
return parent.getRichItemName(itemType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getRichItemName(BaseItemStack itemStack) {
|
||||||
|
return parent.getRichItemName(itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OptionalInt getInternalBlockStateId(BlockState state) {
|
||||||
|
PaperweightBlockMaterial material = (PaperweightBlockMaterial) state.getMaterial();
|
||||||
|
net.minecraft.world.level.block.state.BlockState mcState = material.getCraftBlockData().getState();
|
||||||
|
return OptionalInt.of(Block.BLOCK_STATE_REGISTRY.getId(mcState));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState adapt(BlockData blockData) {
|
||||||
|
CraftBlockData cbd = ((CraftBlockData) blockData);
|
||||||
|
net.minecraft.world.level.block.state.BlockState ibd = cbd.getState();
|
||||||
|
return adapt(ibd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) {
|
||||||
|
return BlockTypesCache.states[adaptToChar(blockState)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockState) {
|
||||||
|
int id = Block.BLOCK_STATE_REGISTRY.getId(blockState);
|
||||||
|
if (initialised) {
|
||||||
|
return ibdToStateOrdinal[id];
|
||||||
|
}
|
||||||
|
synchronized (this) {
|
||||||
|
if (initialised) {
|
||||||
|
return ibdToStateOrdinal[id];
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
init();
|
||||||
|
return ibdToStateOrdinal[id];
|
||||||
|
} catch (ArrayIndexOutOfBoundsException e1) {
|
||||||
|
LOGGER.error("Attempted to convert {} with ID {} to char. ibdToStateOrdinal length: {}. Defaulting to air!",
|
||||||
|
blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToStateOrdinal.length, e1
|
||||||
|
);
|
||||||
|
return BlockTypesCache.ReservedIDs.AIR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public char ibdIDToOrdinal(int id) {
|
||||||
|
if (initialised) {
|
||||||
|
return ibdToStateOrdinal[id];
|
||||||
|
}
|
||||||
|
synchronized (this) {
|
||||||
|
if (initialised) {
|
||||||
|
return ibdToStateOrdinal[id];
|
||||||
|
}
|
||||||
|
init();
|
||||||
|
return ibdToStateOrdinal[id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] getIbdToStateOrdinal() {
|
||||||
|
if (initialised) {
|
||||||
|
return ibdToStateOrdinal;
|
||||||
|
}
|
||||||
|
synchronized (this) {
|
||||||
|
if (initialised) {
|
||||||
|
return ibdToStateOrdinal;
|
||||||
|
}
|
||||||
|
init();
|
||||||
|
return ibdToStateOrdinal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ordinalToIbdID(char ordinal) {
|
||||||
|
if (initialised) {
|
||||||
|
return ordinalToIbdID[ordinal];
|
||||||
|
}
|
||||||
|
synchronized (this) {
|
||||||
|
if (initialised) {
|
||||||
|
return ordinalToIbdID[ordinal];
|
||||||
|
}
|
||||||
|
init();
|
||||||
|
return ordinalToIbdID[ordinal];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] getOrdinalToIbdID() {
|
||||||
|
if (initialised) {
|
||||||
|
return ordinalToIbdID;
|
||||||
|
}
|
||||||
|
synchronized (this) {
|
||||||
|
if (initialised) {
|
||||||
|
return ordinalToIbdID;
|
||||||
|
}
|
||||||
|
init();
|
||||||
|
return ordinalToIbdID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <B extends BlockStateHolder<B>> BlockData adapt(B state) {
|
||||||
|
PaperweightBlockMaterial material = (PaperweightBlockMaterial) state.getMaterial();
|
||||||
|
return material.getCraftBlockData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket chunkPacket) {
|
||||||
|
ServerLevel nmsWorld = ((CraftWorld) world).getHandle();
|
||||||
|
ChunkHolder map = PaperweightPlatformAdapter.getPlayerChunk(nmsWorld, chunkPacket.getChunkX(), chunkPacket.getChunkZ());
|
||||||
|
if (map != null && map.wasAccessibleSinceLastSave()) {
|
||||||
|
boolean flag = false;
|
||||||
|
// PlayerChunk.d players = map.players;
|
||||||
|
Stream<ServerPlayer> stream = /*players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag)
|
||||||
|
*/ Stream.empty();
|
||||||
|
|
||||||
|
ServerPlayer checkPlayer = player == null ? null : ((CraftPlayer) player).getHandle();
|
||||||
|
stream.filter(entityPlayer -> checkPlayer == null || entityPlayer == checkPlayer)
|
||||||
|
.forEach(entityPlayer -> {
|
||||||
|
synchronized (chunkPacket) {
|
||||||
|
ClientboundLevelChunkWithLightPacket nmsPacket = (ClientboundLevelChunkWithLightPacket) chunkPacket.getNativePacket();
|
||||||
|
if (nmsPacket == null) {
|
||||||
|
nmsPacket = mapUtil.create(this, chunkPacket);
|
||||||
|
chunkPacket.setNativePacket(nmsPacket);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
FaweCache.INSTANCE.CHUNK_FLAG.get().set(true);
|
||||||
|
entityPlayer.connection.send(nmsPacket);
|
||||||
|
} finally {
|
||||||
|
FaweCache.INSTANCE.CHUNK_FLAG.get().set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, ? extends Property<?>> getProperties(BlockType blockType) {
|
||||||
|
return getParent().getProperties(blockType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canPlaceAt(org.bukkit.World world, BlockVector3 blockVector3, BlockState blockState) {
|
||||||
|
int internalId = BlockStateIdAccess.getBlockStateId(blockState);
|
||||||
|
net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId);
|
||||||
|
return blockState1.hasPostProcess(
|
||||||
|
((CraftWorld) world).getHandle(),
|
||||||
|
new BlockPos(blockVector3.getX(), blockVector3.getY(), blockVector3.getZ())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.bukkit.inventory.ItemStack adapt(BaseItemStack baseItemStack) {
|
||||||
|
ItemStack stack = new ItemStack(
|
||||||
|
Registry.ITEM.get(ResourceLocation.tryParse(baseItemStack.getType().getId())),
|
||||||
|
baseItemStack.getAmount()
|
||||||
|
);
|
||||||
|
stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(baseItemStack.getNbtData())));
|
||||||
|
return CraftItemStack.asCraftMirror(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean generateTree(
|
||||||
|
TreeGenerator.TreeType treeType, EditSession editSession, BlockVector3 blockVector3,
|
||||||
|
org.bukkit.World bukkitWorld
|
||||||
|
) {
|
||||||
|
TreeType bukkitType = BukkitWorld.toBukkitTreeType(treeType);
|
||||||
|
if (bukkitType == TreeType.CHORUS_PLANT) {
|
||||||
|
blockVector3 = blockVector3.add(
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0
|
||||||
|
); // bukkit skips the feature gen which does this offset normally, so we have to add it back
|
||||||
|
}
|
||||||
|
ServerLevel serverLevel = ((CraftWorld) bukkitWorld).getHandle();
|
||||||
|
serverLevel.captureTreeGeneration = true;
|
||||||
|
serverLevel.captureBlockStates = true;
|
||||||
|
boolean grownTree = bukkitWorld.generateTree(BukkitAdapter.adapt(bukkitWorld, blockVector3), bukkitType);
|
||||||
|
serverLevel.captureBlockStates = false;
|
||||||
|
serverLevel.captureTreeGeneration = false;
|
||||||
|
if (!grownTree) {
|
||||||
|
serverLevel.capturedBlockStates.clear();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
for (CraftBlockState craftBlockState : serverLevel.capturedBlockStates.values()) {
|
||||||
|
if (craftBlockState == null || craftBlockState.getType() == Material.AIR) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
editSession.setBlock(craftBlockState.getX(), craftBlockState.getY(), craftBlockState.getZ(),
|
||||||
|
BukkitAdapter.adapt(((org.bukkit.block.BlockState) craftBlockState).getBlockData())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
serverLevel.capturedBlockStates.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<org.bukkit.entity.Entity> getEntities(org.bukkit.World world) {
|
||||||
|
// Quickly add each entity to a list copy.
|
||||||
|
List<Entity> mcEntities = new ArrayList<>();
|
||||||
|
((CraftWorld) world).getHandle().entityManager.getEntityGetter().getAll().forEach(mcEntities::add);
|
||||||
|
|
||||||
|
List<org.bukkit.entity.Entity> list = new ArrayList<>();
|
||||||
|
mcEntities.forEach((mcEnt) -> {
|
||||||
|
org.bukkit.entity.Entity bukkitEntity = mcEnt.getBukkitEntity();
|
||||||
|
if (bukkitEntity.isValid()) {
|
||||||
|
list.add(bukkitEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) {
|
||||||
|
final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
||||||
|
final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount());
|
||||||
|
weStack.setNbt(((CompoundBinaryTag) toNativeBinary(nmsStack.getTag())));
|
||||||
|
return weStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tag toNative(net.minecraft.nbt.Tag foreign) {
|
||||||
|
return parent.toNative(foreign);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public net.minecraft.nbt.Tag fromNative(Tag foreign) {
|
||||||
|
if (foreign instanceof PaperweightLazyCompoundTag) {
|
||||||
|
return ((PaperweightLazyCompoundTag) foreign).get();
|
||||||
|
}
|
||||||
|
return parent.fromNative(foreign);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean regenerate(org.bukkit.World bukkitWorld, Region region, Extent target, RegenOptions options) throws Exception {
|
||||||
|
return new PaperweightRegen(bukkitWorld, region, target, options).regenerate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IChunkGet get(org.bukkit.World world, int chunkX, int chunkZ) {
|
||||||
|
return new PaperweightGetBlocks(world, chunkX, chunkZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInternalBiomeId(BiomeType biomeType) {
|
||||||
|
if (biomeType.getId().startsWith("minecraft:")) {
|
||||||
|
Biome biomeBase = CraftBlock.biomeToBiomeBase(
|
||||||
|
MinecraftServer.getServer().registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY),
|
||||||
|
BukkitAdapter.adapt(biomeType)
|
||||||
|
);
|
||||||
|
return MinecraftServer.getServer().registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY).getId(biomeBase);
|
||||||
|
} else {
|
||||||
|
WritableRegistry<Biome> biomeRegistry = MinecraftServer.getServer().registryAccess()
|
||||||
|
.ownedRegistryOrThrow(Registry.BIOME_REGISTRY);
|
||||||
|
|
||||||
|
ResourceLocation resourceLocation = biomeRegistry.keySet().stream()
|
||||||
|
.filter(resource -> resource.toString().equals(biomeType.getId()))
|
||||||
|
.findAny().orElse(null);
|
||||||
|
|
||||||
|
return biomeRegistry.getId(biomeRegistry.get(resourceLocation));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<NamespacedKey> getRegisteredBiomes() {
|
||||||
|
WritableRegistry<Biome> biomeRegistry = ((CraftServer) Bukkit.getServer())
|
||||||
|
.getServer()
|
||||||
|
.registryAccess()
|
||||||
|
.ownedRegistryOrThrow(
|
||||||
|
Registry.BIOME_REGISTRY);
|
||||||
|
return biomeRegistry.stream()
|
||||||
|
.map(biomeRegistry::getKey)
|
||||||
|
.map(CraftNamespacedKey::fromMinecraft)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RelighterFactory getRelighterFactory() {
|
||||||
|
try {
|
||||||
|
Class.forName("ca.spottedleaf.starlight.common.light.StarLightEngine");
|
||||||
|
if (PaperweightStarlightRelighter.isUsable()) {
|
||||||
|
return new PaperweightStarlightRelighterFactory();
|
||||||
|
}
|
||||||
|
} catch (ThreadDeath td) {
|
||||||
|
throw td;
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return new NMSRelighterFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, List<Property<?>>> getAllProperties() {
|
||||||
|
if (initialised) {
|
||||||
|
return allBlockProperties;
|
||||||
|
}
|
||||||
|
synchronized (this) {
|
||||||
|
if (initialised) {
|
||||||
|
return allBlockProperties;
|
||||||
|
}
|
||||||
|
init();
|
||||||
|
return allBlockProperties;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,286 @@
|
|||||||
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1;
|
||||||
|
|
||||||
|
import com.fastasyncworldedit.core.Fawe;
|
||||||
|
import com.fastasyncworldedit.core.math.IntPair;
|
||||||
|
import com.fastasyncworldedit.core.util.TaskManager;
|
||||||
|
import com.fastasyncworldedit.core.util.task.RunnableVal;
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
|
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
||||||
|
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
|
||||||
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
|
import com.sk89q.worldedit.util.SideEffectSet;
|
||||||
|
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.level.ChunkHolder;
|
||||||
|
import net.minecraft.server.level.ServerChunkCache;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.block.data.CraftBlockData;
|
||||||
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess<LevelChunk,
|
||||||
|
net.minecraft.world.level.block.state.BlockState, BlockPos> {
|
||||||
|
|
||||||
|
private static final int UPDATE = 1;
|
||||||
|
private static final int NOTIFY = 2;
|
||||||
|
private static final Direction[] NEIGHBOUR_ORDER = {
|
||||||
|
Direction.EAST,
|
||||||
|
Direction.WEST,
|
||||||
|
Direction.DOWN,
|
||||||
|
Direction.UP,
|
||||||
|
Direction.NORTH,
|
||||||
|
Direction.SOUTH
|
||||||
|
};
|
||||||
|
private final PaperweightFaweAdapter paperweightFaweAdapter;
|
||||||
|
private final WeakReference<Level> level;
|
||||||
|
private final AtomicInteger lastTick;
|
||||||
|
private final Set<CachedChange> cachedChanges = new HashSet<>();
|
||||||
|
private final Set<IntPair> cachedChunksToSend = new HashSet<>();
|
||||||
|
private SideEffectSet sideEffectSet;
|
||||||
|
|
||||||
|
public PaperweightFaweWorldNativeAccess(PaperweightFaweAdapter paperweightFaweAdapter, WeakReference<Level> level) {
|
||||||
|
this.paperweightFaweAdapter = paperweightFaweAdapter;
|
||||||
|
this.level = level;
|
||||||
|
// Use the actual tick as minecraft-defined so we don't try to force blocks into the world when the server's already lagging.
|
||||||
|
// - With the caveat that we don't want to have too many cached changed (1024) so we'd flush those at 1024 anyway.
|
||||||
|
this.lastTick = new AtomicInteger(MinecraftServer.currentTick);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Level getLevel() {
|
||||||
|
return Objects.requireNonNull(level.get(), "The reference to the world was lost");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) {
|
||||||
|
this.sideEffectSet = sideEffectSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LevelChunk getChunk(int x, int z) {
|
||||||
|
return getLevel().getChunk(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public net.minecraft.world.level.block.state.BlockState toNative(BlockState blockState) {
|
||||||
|
int stateId = paperweightFaweAdapter.ordinalToIbdID(blockState.getOrdinalChar());
|
||||||
|
return BlockStateIdAccess.isValidInternalId(stateId)
|
||||||
|
? Block.stateById(stateId)
|
||||||
|
: ((CraftBlockData) BukkitAdapter.adapt(blockState)).getState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public net.minecraft.world.level.block.state.BlockState getBlockState(LevelChunk levelChunk, BlockPos blockPos) {
|
||||||
|
return levelChunk.getBlockState(blockPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public synchronized net.minecraft.world.level.block.state.BlockState setBlockState(
|
||||||
|
LevelChunk levelChunk, BlockPos blockPos,
|
||||||
|
net.minecraft.world.level.block.state.BlockState blockState
|
||||||
|
) {
|
||||||
|
int currentTick = MinecraftServer.currentTick;
|
||||||
|
if (Fawe.isMainThread()) {
|
||||||
|
return levelChunk.setBlockState(blockPos, blockState,
|
||||||
|
this.sideEffectSet != null && this.sideEffectSet.shouldApply(SideEffect.UPDATE)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Since FAWE is.. Async we need to do it on the main thread (wooooo.. :( )
|
||||||
|
cachedChanges.add(new CachedChange(levelChunk, blockPos, blockState));
|
||||||
|
cachedChunksToSend.add(new IntPair(levelChunk.bukkitChunk.getX(), levelChunk.bukkitChunk.getZ()));
|
||||||
|
boolean nextTick = lastTick.get() > currentTick;
|
||||||
|
if (nextTick || cachedChanges.size() >= 1024) {
|
||||||
|
if (nextTick) {
|
||||||
|
lastTick.set(currentTick);
|
||||||
|
}
|
||||||
|
flushAsync(nextTick);
|
||||||
|
}
|
||||||
|
return blockState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition(
|
||||||
|
net.minecraft.world.level.block.state.BlockState blockState,
|
||||||
|
BlockPos blockPos
|
||||||
|
) {
|
||||||
|
return Block.updateFromNeighbourShapes(blockState, getLevel(), blockPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockPos getPosition(int x, int y, int z) {
|
||||||
|
return new BlockPos(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateLightingForBlock(BlockPos blockPos) {
|
||||||
|
getLevel().getChunkSource().getLightEngine().checkBlock(blockPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateTileEntity(BlockPos blockPos, CompoundBinaryTag tag) {
|
||||||
|
// We will assume that the tile entity was created for us,
|
||||||
|
// though we do not do this on the other versions
|
||||||
|
BlockEntity blockEntity = getLevel().getBlockEntity(blockPos);
|
||||||
|
if (blockEntity == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
net.minecraft.nbt.Tag nativeTag = paperweightFaweAdapter.fromNativeBinary(tag);
|
||||||
|
blockEntity.load((CompoundTag) nativeTag);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyBlockUpdate(
|
||||||
|
LevelChunk levelChunk, BlockPos blockPos,
|
||||||
|
net.minecraft.world.level.block.state.BlockState oldState,
|
||||||
|
net.minecraft.world.level.block.state.BlockState newState
|
||||||
|
) {
|
||||||
|
if (levelChunk.getSections()[level.get().getSectionIndex(blockPos.getY())] != null) {
|
||||||
|
getLevel().sendBlockUpdated(blockPos, oldState, newState, UPDATE | NOTIFY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChunkTicking(LevelChunk levelChunk) {
|
||||||
|
return levelChunk.getFullStatus().isOrAfter(ChunkHolder.FullChunkStatus.TICKING);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void markBlockChanged(LevelChunk levelChunk, BlockPos blockPos) {
|
||||||
|
if (levelChunk.getSections()[level.get().getSectionIndex(blockPos.getY())] != null) {
|
||||||
|
((ServerChunkCache) getLevel().getChunkSource()).blockChanged(blockPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyNeighbors(
|
||||||
|
BlockPos blockPos,
|
||||||
|
net.minecraft.world.level.block.state.BlockState oldState,
|
||||||
|
net.minecraft.world.level.block.state.BlockState newState
|
||||||
|
) {
|
||||||
|
Level level = getLevel();
|
||||||
|
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
|
||||||
|
level.blockUpdated(blockPos, oldState.getBlock());
|
||||||
|
} else {
|
||||||
|
// When we don't want events, manually run the physics without them.
|
||||||
|
// Un-nest neighbour updating
|
||||||
|
for (Direction direction : NEIGHBOUR_ORDER) {
|
||||||
|
BlockPos shifted = blockPos.relative(direction);
|
||||||
|
level.getBlockState(shifted).neighborChanged(level, shifted, oldState.getBlock(), blockPos, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newState.hasAnalogOutputSignal()) {
|
||||||
|
level.updateNeighbourForOutputSignal(blockPos, newState.getBlock());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNeighbors(
|
||||||
|
BlockPos blockPos,
|
||||||
|
net.minecraft.world.level.block.state.BlockState oldState,
|
||||||
|
net.minecraft.world.level.block.state.BlockState newState,
|
||||||
|
int recursionLimit
|
||||||
|
) {
|
||||||
|
Level level = getLevel();
|
||||||
|
// a == updateNeighbors
|
||||||
|
// b == updateDiagonalNeighbors
|
||||||
|
oldState.updateIndirectNeighbourShapes(level, blockPos, NOTIFY, recursionLimit);
|
||||||
|
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
|
||||||
|
CraftWorld craftWorld = level.getWorld();
|
||||||
|
if (craftWorld != null) {
|
||||||
|
BlockPhysicsEvent event = new BlockPhysicsEvent(
|
||||||
|
craftWorld.getBlockAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()),
|
||||||
|
CraftBlockData.fromData(newState)
|
||||||
|
);
|
||||||
|
level.getCraftServer().getPluginManager().callEvent(event);
|
||||||
|
if (event.isCancelled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newState.triggerEvent(level, blockPos, NOTIFY, recursionLimit);
|
||||||
|
newState.updateIndirectNeighbourShapes(level, blockPos, NOTIFY, recursionLimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBlockStateChange(
|
||||||
|
BlockPos blockPos,
|
||||||
|
net.minecraft.world.level.block.state.BlockState oldState,
|
||||||
|
net.minecraft.world.level.block.state.BlockState newState
|
||||||
|
) {
|
||||||
|
getLevel().onBlockStateChange(blockPos, oldState, newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void flushAsync(final boolean sendChunks) {
|
||||||
|
final Set<CachedChange> changes = Set.copyOf(cachedChanges);
|
||||||
|
cachedChanges.clear();
|
||||||
|
final Set<IntPair> toSend;
|
||||||
|
if (sendChunks) {
|
||||||
|
toSend = Set.copyOf(cachedChunksToSend);
|
||||||
|
cachedChunksToSend.clear();
|
||||||
|
} else {
|
||||||
|
toSend = Collections.emptySet();
|
||||||
|
}
|
||||||
|
RunnableVal<Object> runnableVal = new RunnableVal<>() {
|
||||||
|
@Override
|
||||||
|
public void run(Object value) {
|
||||||
|
changes.forEach(cc -> cc.levelChunk.setBlockState(cc.blockPos, cc.blockState,
|
||||||
|
sideEffectSet != null && sideEffectSet.shouldApply(SideEffect.UPDATE)
|
||||||
|
));
|
||||||
|
if (!sendChunks) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (IntPair chunk : toSend) {
|
||||||
|
PaperweightPlatformAdapter.sendChunk(getLevel().getWorld().getHandle(), chunk.x, chunk.z, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
TaskManager.taskManager().async(() -> TaskManager.taskManager().sync(runnableVal));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void flush() {
|
||||||
|
RunnableVal<Object> runnableVal = new RunnableVal<>() {
|
||||||
|
@Override
|
||||||
|
public void run(Object value) {
|
||||||
|
cachedChanges.forEach(cc -> cc.levelChunk.setBlockState(cc.blockPos, cc.blockState,
|
||||||
|
sideEffectSet != null && sideEffectSet.shouldApply(SideEffect.UPDATE)
|
||||||
|
));
|
||||||
|
for (IntPair chunk : cachedChunksToSend) {
|
||||||
|
PaperweightPlatformAdapter.sendChunk(getLevel().getWorld().getHandle(), chunk.x, chunk.z, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (Fawe.isMainThread()) {
|
||||||
|
runnableVal.run();
|
||||||
|
} else {
|
||||||
|
TaskManager.taskManager().sync(runnableVal);
|
||||||
|
}
|
||||||
|
cachedChanges.clear();
|
||||||
|
cachedChunksToSend.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private record CachedChange(
|
||||||
|
LevelChunk levelChunk,
|
||||||
|
BlockPos blockPos,
|
||||||
|
net.minecraft.world.level.block.state.BlockState blockState
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
@ -0,0 +1,240 @@
|
|||||||
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1;
|
||||||
|
|
||||||
|
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||||
|
import com.fastasyncworldedit.core.queue.IBlocks;
|
||||||
|
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||||
|
import com.fastasyncworldedit.core.queue.IChunkSet;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1.nbt.PaperweightLazyCompoundTag;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
public class PaperweightGetBlocks_Copy implements IChunkGet {
|
||||||
|
|
||||||
|
private final Map<BlockVector3, CompoundTag> tiles = new HashMap<>();
|
||||||
|
private final Set<CompoundTag> entities = new HashSet<>();
|
||||||
|
private final char[][] blocks;
|
||||||
|
private final int minHeight;
|
||||||
|
private final int maxHeight;
|
||||||
|
private final ServerLevel serverLevel;
|
||||||
|
private PalettedContainer<Biome>[] biomes = null;
|
||||||
|
|
||||||
|
protected PaperweightGetBlocks_Copy(ServerLevel world) {
|
||||||
|
this.serverLevel = world;
|
||||||
|
this.minHeight = world.getMinBuildHeight();
|
||||||
|
this.maxHeight = world.getMaxBuildHeight() - 1; // Minecraft max limit is exclusive.
|
||||||
|
this.blocks = new char[getSectionCount()][];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeTile(BlockEntity blockEntity) {
|
||||||
|
tiles.put(
|
||||||
|
BlockVector3.at(
|
||||||
|
blockEntity.getBlockPos().getX(),
|
||||||
|
blockEntity.getBlockPos().getY(),
|
||||||
|
blockEntity.getBlockPos().getZ()
|
||||||
|
),
|
||||||
|
new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<BlockVector3, CompoundTag> getTiles() {
|
||||||
|
return tiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public CompoundTag getTile(int x, int y, int z) {
|
||||||
|
return tiles.get(BlockVector3.at(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeEntity(Entity entity) {
|
||||||
|
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
|
||||||
|
net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag();
|
||||||
|
entities.add((CompoundTag) adapter.toNative(entity.save(compoundTag)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<CompoundTag> getEntities() {
|
||||||
|
return this.entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundTag getEntity(UUID uuid) {
|
||||||
|
for (CompoundTag tag : entities) {
|
||||||
|
UUID tagUUID;
|
||||||
|
if (tag.containsKey("UUID")) {
|
||||||
|
int[] arr = tag.getIntArray("UUID");
|
||||||
|
tagUUID = new UUID((long) arr[0] << 32 | (arr[1] & 0xFFFFFFFFL), (long) arr[2] << 32 | (arr[3] & 0xFFFFFFFFL));
|
||||||
|
} else if (tag.containsKey("UUIDMost")) {
|
||||||
|
tagUUID = new UUID(tag.getLong("UUIDMost"), tag.getLong("UUIDLeast"));
|
||||||
|
} else if (tag.containsKey("PersistentIDMSB")) {
|
||||||
|
tagUUID = new UUID(tag.getLong("PersistentIDMSB"), tag.getLong("PersistentIDLSB"));
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (uuid.equals(tagUUID)) {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCreateCopy() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCreateCopy(boolean createCopy) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLightingToGet(char[][] lighting, int minSectionPosition, int maxSectionPosition) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSkyLightingToGet(char[][] lighting, int minSectionPosition, int maxSectionPosition) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHeightmapToGet(HeightMapType type, int[] data) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxY() {
|
||||||
|
return maxHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinY() {
|
||||||
|
return minHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxSectionPosition() {
|
||||||
|
return maxHeight >> 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinSectionPosition() {
|
||||||
|
return minHeight >> 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeType getBiomeType(int x, int y, int z) {
|
||||||
|
Biome biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2);
|
||||||
|
return biome != null ? PaperweightPlatformAdapter.adapt(biome, serverLevel) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSectionLighting(int layer, boolean sky) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBlocks reset() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSectionCount() {
|
||||||
|
return serverLevel.getSectionsCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeSection(int layer, char[] data) {
|
||||||
|
blocks[layer] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void storeBiomes(int layer, PalettedContainer<Biome> biomeData) {
|
||||||
|
if (biomes == null) {
|
||||||
|
biomes = new PalettedContainer[getSectionCount()];
|
||||||
|
}
|
||||||
|
biomes[layer] = biomeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||||
|
BlockState state = BlockTypesCache.states[get(x, y, z)];
|
||||||
|
return state.toBaseBlock(this, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSection(int layer) {
|
||||||
|
layer -= getMinSectionPosition();
|
||||||
|
return blocks[layer] != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] load(int layer) {
|
||||||
|
layer -= getMinSectionPosition();
|
||||||
|
return blocks[layer];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] loadIfPresent(int layer) {
|
||||||
|
layer -= getMinSectionPosition();
|
||||||
|
return blocks[layer];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlock(int x, int y, int z) {
|
||||||
|
return BlockTypesCache.states[get(x, y, z)];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSkyLight(int x, int y, int z) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEmittedLight(int x, int y, int z) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] getHeightMap(HeightMapType type) {
|
||||||
|
return new int[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends Future<T>> T call(IChunkSet set, Runnable finalize) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public char get(int x, int y, int z) {
|
||||||
|
final int layer = (y >> 4) - getMinSectionPosition();
|
||||||
|
final int index = (y & 15) << 8 | z << 4 | x;
|
||||||
|
return blocks[layer][index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean trim(boolean aggressive) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1;
|
||||||
|
|
||||||
|
import com.fastasyncworldedit.bukkit.adapter.MapChunkUtil;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData;
|
||||||
|
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
|
||||||
|
|
||||||
|
//TODO un-very-break-this
|
||||||
|
public class PaperweightMapChunkUtil extends MapChunkUtil<ClientboundLevelChunkWithLightPacket> {
|
||||||
|
|
||||||
|
public PaperweightMapChunkUtil() throws NoSuchFieldException {
|
||||||
|
fieldX = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("TWO_MEGABYTES", "a"));
|
||||||
|
fieldZ = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("x", "a"));
|
||||||
|
fieldBitMask = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("z", "b"));
|
||||||
|
fieldHeightMap = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("heightmaps", "b"));
|
||||||
|
fieldChunkData = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("chunkData", "c"));
|
||||||
|
fieldBlockEntities = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("buffer", "c"));
|
||||||
|
fieldFull = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("blockEntitiesData", "d"));
|
||||||
|
fieldX.setAccessible(true);
|
||||||
|
fieldZ.setAccessible(true);
|
||||||
|
fieldBitMask.setAccessible(true);
|
||||||
|
fieldHeightMap.setAccessible(true);
|
||||||
|
fieldChunkData.setAccessible(true);
|
||||||
|
fieldBlockEntities.setAccessible(true);
|
||||||
|
fieldFull.setAccessible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientboundLevelChunkWithLightPacket createPacket() {
|
||||||
|
// TODO ??? return new ClientboundLevelChunkPacket();
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,661 @@
|
|||||||
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1;
|
||||||
|
|
||||||
|
import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter;
|
||||||
|
import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore;
|
||||||
|
import com.fastasyncworldedit.bukkit.adapter.NMSAdapter;
|
||||||
|
import com.fastasyncworldedit.core.Fawe;
|
||||||
|
import com.fastasyncworldedit.core.FaweCache;
|
||||||
|
import com.fastasyncworldedit.core.math.BitArrayUnstretched;
|
||||||
|
import com.fastasyncworldedit.core.util.MathMan;
|
||||||
|
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
||||||
|
import com.fastasyncworldedit.core.util.TaskManager;
|
||||||
|
import com.mojang.datafixers.util.Either;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
|
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||||
|
import io.papermc.lib.PaperLib;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.IdMap;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.core.SectionPos;
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.level.ChunkHolder;
|
||||||
|
import net.minecraft.server.level.ChunkMap;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.util.BitStorage;
|
||||||
|
import net.minecraft.util.SimpleBitStorage;
|
||||||
|
import net.minecraft.util.ThreadingDetector;
|
||||||
|
import net.minecraft.util.ZeroBitStorage;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.biome.Biomes;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.chunk.GlobalPalette;
|
||||||
|
import net.minecraft.world.level.chunk.HashMapPalette;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||||
|
import net.minecraft.world.level.chunk.LinearPalette;
|
||||||
|
import net.minecraft.world.level.chunk.Palette;
|
||||||
|
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||||
|
import net.minecraft.world.level.chunk.SingleValuePalette;
|
||||||
|
import net.minecraft.world.level.gameevent.GameEventDispatcher;
|
||||||
|
import net.minecraft.world.level.gameevent.GameEventListener;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.CraftChunk;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||||
|
|
||||||
|
public static final Field fieldData;
|
||||||
|
|
||||||
|
public static final Constructor<?> dataConstructor;
|
||||||
|
|
||||||
|
public static final Field fieldStorage;
|
||||||
|
public static final Field fieldPalette;
|
||||||
|
|
||||||
|
|
||||||
|
public static final Field fieldTickingFluidCount;
|
||||||
|
public static final Field fieldTickingBlockCount;
|
||||||
|
public static final Field fieldNonEmptyBlockCount;
|
||||||
|
|
||||||
|
private static final MethodHandle methodGetVisibleChunk;
|
||||||
|
|
||||||
|
private static final int CHUNKSECTION_BASE;
|
||||||
|
private static final int CHUNKSECTION_SHIFT;
|
||||||
|
|
||||||
|
private static final Field fieldThreadingDetector;
|
||||||
|
private static final long fieldThreadingDetectorOffset;
|
||||||
|
|
||||||
|
private static final Field fieldLock;
|
||||||
|
private static final long fieldLockOffset;
|
||||||
|
|
||||||
|
private static final Field fieldGameEventDispatcherSections;
|
||||||
|
private static final MethodHandle methodremoveTickingBlockEntity;
|
||||||
|
|
||||||
|
private static final Field fieldRemove;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
fieldData = PalettedContainer.class.getDeclaredField(Refraction.pickName("data", "d"));
|
||||||
|
fieldData.setAccessible(true);
|
||||||
|
|
||||||
|
Class<?> dataClazz = fieldData.getType();
|
||||||
|
dataConstructor = dataClazz.getDeclaredConstructors()[0];
|
||||||
|
dataConstructor.setAccessible(true);
|
||||||
|
|
||||||
|
fieldStorage = dataClazz.getDeclaredField(Refraction.pickName("storage", "b"));
|
||||||
|
fieldStorage.setAccessible(true);
|
||||||
|
fieldPalette = dataClazz.getDeclaredField(Refraction.pickName("palette", "c"));
|
||||||
|
fieldPalette.setAccessible(true);
|
||||||
|
|
||||||
|
fieldTickingFluidCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingFluidCount", "h"));
|
||||||
|
fieldTickingFluidCount.setAccessible(true);
|
||||||
|
fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "g"));
|
||||||
|
fieldTickingBlockCount.setAccessible(true);
|
||||||
|
fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "f"));
|
||||||
|
fieldNonEmptyBlockCount.setAccessible(true);
|
||||||
|
|
||||||
|
Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName(
|
||||||
|
"getVisibleChunkIfPresent",
|
||||||
|
"b"
|
||||||
|
), long.class);
|
||||||
|
getVisibleChunkIfPresent.setAccessible(true);
|
||||||
|
methodGetVisibleChunk = MethodHandles.lookup().unreflect(getVisibleChunkIfPresent);
|
||||||
|
|
||||||
|
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
||||||
|
fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f"));
|
||||||
|
fieldThreadingDetectorOffset = unsafe.objectFieldOffset(fieldThreadingDetector);
|
||||||
|
|
||||||
|
fieldLock = ThreadingDetector.class.getDeclaredField(Refraction.pickName("lock", "c"));
|
||||||
|
fieldLockOffset = unsafe.objectFieldOffset(fieldLock);
|
||||||
|
|
||||||
|
fieldGameEventDispatcherSections = LevelChunk.class.getDeclaredField(Refraction.pickName(
|
||||||
|
"gameEventDispatcherSections", "t"));
|
||||||
|
fieldGameEventDispatcherSections.setAccessible(true);
|
||||||
|
Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod(
|
||||||
|
Refraction.pickName(
|
||||||
|
"removeBlockEntityTicker",
|
||||||
|
"m"
|
||||||
|
), BlockPos.class
|
||||||
|
);
|
||||||
|
removeBlockEntityTicker.setAccessible(true);
|
||||||
|
methodremoveTickingBlockEntity = MethodHandles.lookup().unreflect(removeBlockEntityTicker);
|
||||||
|
|
||||||
|
fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "p"));
|
||||||
|
fieldRemove.setAccessible(true);
|
||||||
|
|
||||||
|
CHUNKSECTION_BASE = unsafe.arrayBaseOffset(LevelChunkSection[].class);
|
||||||
|
int scale = unsafe.arrayIndexScale(LevelChunkSection[].class);
|
||||||
|
if ((scale & (scale - 1)) != 0) {
|
||||||
|
throw new Error("data type scale not a power of two");
|
||||||
|
}
|
||||||
|
CHUNKSECTION_SHIFT = 31 - Integer.numberOfLeadingZeros(scale);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (Throwable rethrow) {
|
||||||
|
rethrow.printStackTrace();
|
||||||
|
throw new RuntimeException(rethrow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean setSectionAtomic(
|
||||||
|
LevelChunkSection[] sections,
|
||||||
|
LevelChunkSection expected,
|
||||||
|
LevelChunkSection value,
|
||||||
|
int layer
|
||||||
|
) {
|
||||||
|
long offset = ((long) layer << CHUNKSECTION_SHIFT) + CHUNKSECTION_BASE;
|
||||||
|
if (layer >= 0 && layer < sections.length) {
|
||||||
|
return ReflectionUtils.getUnsafe().compareAndSwapObject(sections, offset, expected, value);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DelegateSemaphore applyLock(LevelChunkSection section) {
|
||||||
|
try {
|
||||||
|
synchronized (section) {
|
||||||
|
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
||||||
|
PalettedContainer<net.minecraft.world.level.block.state.BlockState> blocks = section.getStates();
|
||||||
|
ThreadingDetector currentThreadingDetector = (ThreadingDetector) unsafe.getObject(blocks,
|
||||||
|
fieldThreadingDetectorOffset) ;
|
||||||
|
synchronized(currentThreadingDetector) {
|
||||||
|
Semaphore currentLock = (Semaphore) unsafe.getObject(currentThreadingDetector, fieldLockOffset);
|
||||||
|
if (currentLock instanceof DelegateSemaphore) {
|
||||||
|
return (DelegateSemaphore) currentLock;
|
||||||
|
}
|
||||||
|
DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock);
|
||||||
|
unsafe.putObject(currentThreadingDetector, fieldLockOffset, newLock);
|
||||||
|
return newLock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LevelChunk ensureLoaded(ServerLevel serverLevel, int chunkX, int chunkZ) {
|
||||||
|
if (!PaperLib.isPaper()) {
|
||||||
|
LevelChunk nmsChunk = serverLevel.getChunkSource().getChunk(chunkX, chunkZ, false);
|
||||||
|
if (nmsChunk != null) {
|
||||||
|
return nmsChunk;
|
||||||
|
}
|
||||||
|
if (Fawe.isMainThread()) {
|
||||||
|
return serverLevel.getChunk(chunkX, chunkZ);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LevelChunk nmsChunk = serverLevel.getChunkSource().getChunkAtIfCachedImmediately(chunkX, chunkZ);
|
||||||
|
if (nmsChunk != null) {
|
||||||
|
return nmsChunk;
|
||||||
|
}
|
||||||
|
nmsChunk = serverLevel.getChunkSource().getChunkAtIfLoadedImmediately(chunkX, chunkZ);
|
||||||
|
if (nmsChunk != null) {
|
||||||
|
return nmsChunk;
|
||||||
|
}
|
||||||
|
// Avoid "async" methods from the main thread.
|
||||||
|
if (Fawe.isMainThread()) {
|
||||||
|
return serverLevel.getChunk(chunkX, chunkZ);
|
||||||
|
}
|
||||||
|
CompletableFuture<org.bukkit.Chunk> future = serverLevel.getWorld().getChunkAtAsync(chunkX, chunkZ, true, true);
|
||||||
|
try {
|
||||||
|
CraftChunk chunk = (CraftChunk) future.get();
|
||||||
|
return chunk.getHandle();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TaskManager.taskManager().sync(() -> serverLevel.getChunk(chunkX, chunkZ));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChunkHolder getPlayerChunk(ServerLevel nmsWorld, final int chunkX, final int chunkZ) {
|
||||||
|
ChunkMap chunkMap = nmsWorld.getChunkSource().chunkMap;
|
||||||
|
try {
|
||||||
|
return (ChunkHolder) methodGetVisibleChunk.invoke(chunkMap, ChunkPos.asLong(chunkX, chunkZ));
|
||||||
|
} catch (Throwable thr) {
|
||||||
|
throw new RuntimeException(thr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendChunk(ServerLevel nmsWorld, int chunkX, int chunkZ, boolean lighting) {
|
||||||
|
ChunkHolder chunkHolder = getPlayerChunk(nmsWorld, chunkX, chunkZ);
|
||||||
|
if (chunkHolder == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ);
|
||||||
|
// UNLOADED_CHUNK
|
||||||
|
Optional<LevelChunk> optional = ((Either) chunkHolder
|
||||||
|
.getTickingChunkFuture()
|
||||||
|
.getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left();
|
||||||
|
if (PaperLib.isPaper()) {
|
||||||
|
// getChunkAtIfLoadedImmediately is paper only
|
||||||
|
optional = optional.or(() -> Optional.ofNullable(nmsWorld
|
||||||
|
.getChunkSource()
|
||||||
|
.getChunkAtIfLoadedImmediately(chunkX, chunkZ)));
|
||||||
|
}
|
||||||
|
if (optional.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LevelChunk levelChunk = optional.get();
|
||||||
|
TaskManager.taskManager().task(() -> {
|
||||||
|
ClientboundLevelChunkWithLightPacket packet;
|
||||||
|
if (PaperLib.isPaper()) {
|
||||||
|
packet = new ClientboundLevelChunkWithLightPacket(
|
||||||
|
levelChunk,
|
||||||
|
nmsWorld.getChunkSource().getLightEngine(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
false // last false is to not bother with x-ray
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// deprecated on paper
|
||||||
|
//noinspection deprecation
|
||||||
|
packet = new ClientboundLevelChunkWithLightPacket(
|
||||||
|
levelChunk,
|
||||||
|
nmsWorld.getChunkSource().getLightEngine(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<ServerPlayer> nearbyPlayers(ServerLevel serverLevel, ChunkPos coordIntPair) {
|
||||||
|
return serverLevel.getChunkSource().chunkMap.getPlayers(coordIntPair, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
NMS conversion
|
||||||
|
*/
|
||||||
|
public static LevelChunkSection newChunkSection(
|
||||||
|
final int layer, final char[] blocks, boolean fastmode,
|
||||||
|
CachedBukkitAdapter adapter, Registry<Biome> biomeRegistry,
|
||||||
|
@Nullable PalettedContainer<Biome> biomes
|
||||||
|
) {
|
||||||
|
return newChunkSection(layer, null, blocks, fastmode, adapter, biomeRegistry, biomes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LevelChunkSection newChunkSection(
|
||||||
|
final int layer, final Function<Integer, char[]> get, char[] set,
|
||||||
|
boolean fastmode, CachedBukkitAdapter adapter, Registry<Biome> biomeRegistry,
|
||||||
|
@Nullable PalettedContainer<Biome> biomes
|
||||||
|
) {
|
||||||
|
if (set == null) {
|
||||||
|
return newChunkSection(layer, biomeRegistry, biomes);
|
||||||
|
}
|
||||||
|
final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get();
|
||||||
|
final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get();
|
||||||
|
final long[] blockStates = FaweCache.INSTANCE.BLOCK_STATES.get();
|
||||||
|
final int[] blocksCopy = FaweCache.INSTANCE.SECTION_BLOCKS.get();
|
||||||
|
try {
|
||||||
|
int[] num_palette_buffer = new int[1];
|
||||||
|
Map<BlockVector3, Integer> ticking_blocks = new HashMap<>();
|
||||||
|
int air;
|
||||||
|
if (get == null) {
|
||||||
|
air = createPalette(blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer,
|
||||||
|
set, ticking_blocks, fastmode, adapter
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
air = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy,
|
||||||
|
num_palette_buffer, get, set, ticking_blocks, fastmode, adapter
|
||||||
|
);
|
||||||
|
}
|
||||||
|
int num_palette = num_palette_buffer[0];
|
||||||
|
// BlockStates
|
||||||
|
|
||||||
|
int bitsPerEntry = MathMan.log2nlz(num_palette - 1);
|
||||||
|
Object configuration =
|
||||||
|
PalettedContainer.Strategy.SECTION_STATES.getConfiguration(new FakeIdMapBlock(num_palette), bitsPerEntry);
|
||||||
|
if (bitsPerEntry > 0 && bitsPerEntry < 5) {
|
||||||
|
bitsPerEntry = 4;
|
||||||
|
} else if (bitsPerEntry > 8) {
|
||||||
|
bitsPerEntry = MathMan.log2nlz(Block.BLOCK_STATE_REGISTRY.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bitsPerEntryNonZero = Math.max(bitsPerEntry, 1); // We do want to use zero sometimes
|
||||||
|
final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntryNonZero);
|
||||||
|
final int blockBitArrayEnd = MathMan.ceilZero((float) 4096 / blocksPerLong);
|
||||||
|
|
||||||
|
if (num_palette == 1) {
|
||||||
|
for (int i = 0; i < blockBitArrayEnd; i++) {
|
||||||
|
blockStates[i] = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntryNonZero, 4096, blockStates);
|
||||||
|
bitArray.fromRaw(blocksCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
final long[] bits = Arrays.copyOfRange(blockStates, 0, blockBitArrayEnd);
|
||||||
|
final BitStorage nmsBits;
|
||||||
|
if (bitsPerEntry == 0) {
|
||||||
|
nmsBits = new ZeroBitStorage(4096);
|
||||||
|
} else {
|
||||||
|
nmsBits = new SimpleBitStorage(bitsPerEntry, 4096, bits);
|
||||||
|
}
|
||||||
|
final Palette<net.minecraft.world.level.block.state.BlockState> blockStatePalette;
|
||||||
|
List<net.minecraft.world.level.block.state.BlockState> palette;
|
||||||
|
if (bitsPerEntry < 9) {
|
||||||
|
palette = new ArrayList<>();
|
||||||
|
for (int i = 0; i < num_palette; i++) {
|
||||||
|
int ordinal = paletteToBlock[i];
|
||||||
|
blockToPalette[ordinal] = Integer.MAX_VALUE;
|
||||||
|
final BlockState state = BlockTypesCache.states[ordinal];
|
||||||
|
palette.add(((PaperweightBlockMaterial) state.getMaterial()).getState());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
palette = List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create palette with data
|
||||||
|
@SuppressWarnings("deprecation") // constructor is deprecated on paper, but needed to keep compatibility with spigot
|
||||||
|
final PalettedContainer<net.minecraft.world.level.block.state.BlockState> blockStatePalettedContainer =
|
||||||
|
new PalettedContainer<>(
|
||||||
|
Block.BLOCK_STATE_REGISTRY,
|
||||||
|
PalettedContainer.Strategy.SECTION_STATES,
|
||||||
|
PalettedContainer.Strategy.SECTION_STATES.getConfiguration(Block.BLOCK_STATE_REGISTRY, bitsPerEntry),
|
||||||
|
nmsBits,
|
||||||
|
palette
|
||||||
|
);
|
||||||
|
LevelChunkSection levelChunkSection;
|
||||||
|
try {
|
||||||
|
//fieldStorage.set(dataPaletteBlocks, nmsBits);
|
||||||
|
//fieldPalette.set(dataPaletteBlocks, blockStatePalettedContainer);
|
||||||
|
if (biomes == null) {
|
||||||
|
biomes = new PalettedContainer<>(
|
||||||
|
biomeRegistry,
|
||||||
|
biomeRegistry.getOrThrow(Biomes.PLAINS),
|
||||||
|
PalettedContainer.Strategy.SECTION_BIOMES,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
levelChunkSection = new LevelChunkSection(layer, blockStatePalettedContainer, biomes);
|
||||||
|
setCount(ticking_blocks.size(), 4096 - air, levelChunkSection);
|
||||||
|
if (!fastmode) {
|
||||||
|
ticking_blocks.forEach((pos, ordinal) -> levelChunkSection.setBlockState(
|
||||||
|
pos.getBlockX(),
|
||||||
|
pos.getBlockY(),
|
||||||
|
pos.getBlockZ(),
|
||||||
|
Block.stateById(ordinal)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} catch (final IllegalAccessException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return levelChunkSection;
|
||||||
|
} catch (final Throwable e) {
|
||||||
|
Arrays.fill(blockToPalette, Integer.MAX_VALUE);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LevelChunkSection newChunkSection(
|
||||||
|
int layer, Registry<Biome> biomeRegistry,
|
||||||
|
@Nullable PalettedContainer<Biome> biomes
|
||||||
|
) {
|
||||||
|
PalettedContainer<net.minecraft.world.level.block.state.BlockState> dataPaletteBlocks = new PalettedContainer<>(
|
||||||
|
Block.BLOCK_STATE_REGISTRY,
|
||||||
|
Blocks.AIR.defaultBlockState(),
|
||||||
|
PalettedContainer.Strategy.SECTION_STATES,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
PalettedContainer<Biome> biomesPalette = biomes != null ? biomes : new PalettedContainer<>(
|
||||||
|
biomeRegistry,
|
||||||
|
biomeRegistry.getOrThrow(Biomes.PLAINS),
|
||||||
|
PalettedContainer.Strategy.SECTION_BIOMES,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
return new LevelChunkSection(layer, dataPaletteBlocks, biomesPalette);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link PalettedContainer<Biome>}. Should only be used if no biome container existed beforehand.
|
||||||
|
*/
|
||||||
|
public static PalettedContainer<Biome> getBiomePalettedContainer(BiomeType[] biomes, Registry<Biome> biomeRegistry) {
|
||||||
|
if (biomes == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Don't stream this as typically will see 1-4 biomes; stream overhead is large for the small length
|
||||||
|
Map<BiomeType, Biome> palette = new HashMap<>();
|
||||||
|
for (BiomeType biomeType : new LinkedList<>(Arrays.asList(biomes))) {
|
||||||
|
Biome biome;
|
||||||
|
if (biomeType == null) {
|
||||||
|
biome = biomeRegistry.getOrThrow(Biomes.PLAINS);
|
||||||
|
} else {
|
||||||
|
biome = biomeRegistry.get(ResourceLocation.tryParse(biomeType.getId()));
|
||||||
|
}
|
||||||
|
palette.put(biomeType, biome);
|
||||||
|
}
|
||||||
|
int biomeCount = palette.size();
|
||||||
|
int bitsPerEntry = MathMan.log2nlz(biomeCount - 1);
|
||||||
|
Object configuration = PalettedContainer.Strategy.SECTION_STATES.getConfiguration(
|
||||||
|
new FakeIdMapBiome(biomeCount),
|
||||||
|
bitsPerEntry
|
||||||
|
);
|
||||||
|
if (bitsPerEntry > 3) {
|
||||||
|
bitsPerEntry = MathMan.log2nlz(biomeRegistry.size() - 1);
|
||||||
|
}
|
||||||
|
PalettedContainer<Biome> biomePalettedContainer = new PalettedContainer<>(
|
||||||
|
biomeRegistry,
|
||||||
|
biomeRegistry.getOrThrow(Biomes.PLAINS),
|
||||||
|
PalettedContainer.Strategy.SECTION_BIOMES,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
final Palette<Biome> biomePalette;
|
||||||
|
if (bitsPerEntry == 0) {
|
||||||
|
biomePalette = new SingleValuePalette<>(
|
||||||
|
biomePalettedContainer.registry,
|
||||||
|
biomePalettedContainer,
|
||||||
|
new ArrayList<>(palette.values()) // Must be modifiable
|
||||||
|
);
|
||||||
|
} else if (bitsPerEntry == 4) {
|
||||||
|
biomePalette = LinearPalette.create(
|
||||||
|
4,
|
||||||
|
biomePalettedContainer.registry,
|
||||||
|
biomePalettedContainer,
|
||||||
|
new ArrayList<>(palette.values()) // Must be modifiable
|
||||||
|
);
|
||||||
|
} else if (bitsPerEntry < 9) {
|
||||||
|
biomePalette = HashMapPalette.create(
|
||||||
|
bitsPerEntry,
|
||||||
|
biomePalettedContainer.registry,
|
||||||
|
biomePalettedContainer,
|
||||||
|
new ArrayList<>(palette.values()) // Must be modifiable
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
biomePalette = GlobalPalette.create(
|
||||||
|
bitsPerEntry,
|
||||||
|
biomePalettedContainer.registry,
|
||||||
|
biomePalettedContainer,
|
||||||
|
null // unused
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bitsPerEntryNonZero = Math.max(bitsPerEntry, 1); // We do want to use zero sometimes
|
||||||
|
final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntryNonZero);
|
||||||
|
final int arrayLength = MathMan.ceilZero(64f / blocksPerLong);
|
||||||
|
|
||||||
|
|
||||||
|
BitStorage bitStorage = bitsPerEntry == 0 ? new ZeroBitStorage(64) : new SimpleBitStorage(
|
||||||
|
bitsPerEntry,
|
||||||
|
64,
|
||||||
|
new long[arrayLength]
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Object data = dataConstructor.newInstance(configuration, bitStorage, biomePalette);
|
||||||
|
fieldData.set(biomePalettedContainer, data);
|
||||||
|
int index = 0;
|
||||||
|
for (int y = 0; y < 4; y++) {
|
||||||
|
for (int z = 0; z < 4; z++) {
|
||||||
|
for (int x = 0; x < 4; x++, index++) {
|
||||||
|
BiomeType biomeType = biomes[index];
|
||||||
|
if (biomeType == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Biome biome = biomeRegistry.get(ResourceLocation.tryParse(biomeType.getId()));
|
||||||
|
if (biome == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
biomePalettedContainer.set(x, y, z, biome);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return biomePalettedContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setCount(final int tickingBlockCount, final int nonEmptyBlockCount, final LevelChunkSection section) throws
|
||||||
|
IllegalAccessException {
|
||||||
|
fieldTickingFluidCount.setShort(section, (short) 0); // TODO FIXME
|
||||||
|
fieldTickingBlockCount.setShort(section, (short) tickingBlockCount);
|
||||||
|
fieldNonEmptyBlockCount.setShort(section, (short) nonEmptyBlockCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BiomeType adapt(Biome biome, LevelAccessor levelAccessor) {
|
||||||
|
ResourceLocation resourceLocation = levelAccessor.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY).getKey(
|
||||||
|
biome);
|
||||||
|
if (resourceLocation == null) {
|
||||||
|
return levelAccessor.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY).getId(biome) == -1
|
||||||
|
? BiomeTypes.OCEAN
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
return BiomeTypes.get(resourceLocation.toString().toLowerCase(Locale.ROOT));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) {
|
||||||
|
try {
|
||||||
|
// Do the method ourselves to avoid trying to reflect generic method parameters
|
||||||
|
// similar to removeGameEventListener
|
||||||
|
if (levelChunk.loaded || levelChunk.level.isClientSide()) {
|
||||||
|
BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos());
|
||||||
|
if (blockEntity != null) {
|
||||||
|
if (!levelChunk.level.isClientSide) {
|
||||||
|
Block block = beacon.getBlockState().getBlock();
|
||||||
|
if (block instanceof EntityBlock) {
|
||||||
|
GameEventListener gameEventListener = ((EntityBlock) block).getListener(levelChunk.level, beacon);
|
||||||
|
if (gameEventListener != null) {
|
||||||
|
int i = SectionPos.blockToSectionCoord(beacon.getBlockPos().getY());
|
||||||
|
GameEventDispatcher gameEventDispatcher = levelChunk.getEventDispatcher(i);
|
||||||
|
gameEventDispatcher.unregister(gameEventListener);
|
||||||
|
if (gameEventDispatcher.isEmpty()) {
|
||||||
|
try {
|
||||||
|
((Int2ObjectMap<GameEventDispatcher>) fieldGameEventDispatcherSections.get(levelChunk))
|
||||||
|
.remove(i);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fieldRemove.set(beacon, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
methodremoveTickingBlockEntity.invoke(levelChunk, beacon.getBlockPos());
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
throwable.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class FakeIdMapBlock implements IdMap<net.minecraft.world.level.block.state.BlockState> {
|
||||||
|
|
||||||
|
private final int size;
|
||||||
|
|
||||||
|
FakeIdMapBlock(int size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId(final net.minecraft.world.level.block.state.BlockState entry) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public net.minecraft.world.level.block.state.BlockState byId(final int index) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Iterator<net.minecraft.world.level.block.state.BlockState> iterator() {
|
||||||
|
return Collections.emptyIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class FakeIdMapBiome implements IdMap<Biome> {
|
||||||
|
|
||||||
|
private final int size;
|
||||||
|
|
||||||
|
FakeIdMapBiome(int size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId(final Biome entry) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Biome byId(final int index) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Iterator<Biome> iterator() {
|
||||||
|
return Collections.emptyIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,238 @@
|
|||||||
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1;
|
||||||
|
|
||||||
|
import com.fastasyncworldedit.core.configuration.Settings;
|
||||||
|
import com.fastasyncworldedit.core.extent.processor.lighting.NMSRelighter;
|
||||||
|
import com.fastasyncworldedit.core.extent.processor.lighting.Relighter;
|
||||||
|
import com.fastasyncworldedit.core.queue.IQueueChunk;
|
||||||
|
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
||||||
|
import com.fastasyncworldedit.core.util.MathMan;
|
||||||
|
import com.fastasyncworldedit.core.util.TaskManager;
|
||||||
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
|
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
|
||||||
|
import it.unimi.dsi.fastutil.longs.LongArraySet;
|
||||||
|
import it.unimi.dsi.fastutil.longs.LongIterator;
|
||||||
|
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||||
|
import net.minecraft.server.MCUtil;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ThreadedLevelLightEngine;
|
||||||
|
import net.minecraft.server.level.TicketType;
|
||||||
|
import net.minecraft.util.Unit;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.IntConsumer;
|
||||||
|
|
||||||
|
public class PaperweightStarlightRelighter implements Relighter {
|
||||||
|
|
||||||
|
public static final MethodHandle RELIGHT;
|
||||||
|
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||||
|
private static final int CHUNKS_PER_BATCH = 1024; // 32 * 32
|
||||||
|
private static final int CHUNKS_PER_BATCH_SQRT_LOG2 = 5; // for shifting
|
||||||
|
|
||||||
|
private static final TicketType<Unit> FAWE_TICKET = TicketType.create("fawe_ticket", (a, b) -> 0);
|
||||||
|
private static final int LIGHT_LEVEL = MCUtil.getTicketLevelFor(ChunkStatus.LIGHT);
|
||||||
|
|
||||||
|
static {
|
||||||
|
MethodHandle tmp = null;
|
||||||
|
try {
|
||||||
|
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||||
|
tmp = lookup.findVirtual(
|
||||||
|
ThreadedLevelLightEngine.class,
|
||||||
|
"relight",
|
||||||
|
MethodType.methodType(
|
||||||
|
int.class, // return type
|
||||||
|
// params
|
||||||
|
Set.class,
|
||||||
|
Consumer.class,
|
||||||
|
IntConsumer.class
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} catch (NoSuchMethodException | IllegalAccessException e) {
|
||||||
|
LOGGER.error("Failed to locate 'relight' method in ThreadedLevelLightEngine. Is everything up to date?", e);
|
||||||
|
}
|
||||||
|
RELIGHT = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ServerLevel serverLevel;
|
||||||
|
private final ReentrantLock lock = new ReentrantLock();
|
||||||
|
private final Long2ObjectLinkedOpenHashMap<LongSet> regions = new Long2ObjectLinkedOpenHashMap<>();
|
||||||
|
private final ReentrantLock areaLock = new ReentrantLock();
|
||||||
|
private final NMSRelighter delegate;
|
||||||
|
|
||||||
|
public PaperweightStarlightRelighter(ServerLevel serverLevel, IQueueExtent<IQueueChunk> queue) {
|
||||||
|
this.serverLevel = serverLevel;
|
||||||
|
this.delegate = new NMSRelighter(queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isUsable() {
|
||||||
|
return RELIGHT != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addChunk(int cx, int cz, byte[] skipReason, int bitmask) {
|
||||||
|
areaLock.lock();
|
||||||
|
try {
|
||||||
|
long key = MathMan.pairInt(cx >> CHUNKS_PER_BATCH_SQRT_LOG2, cz >> CHUNKS_PER_BATCH_SQRT_LOG2);
|
||||||
|
// TODO probably submit here already if chunks.size == CHUNKS_PER_BATCH?
|
||||||
|
LongSet chunks = this.regions.computeIfAbsent(key, k -> new LongArraySet(CHUNKS_PER_BATCH >> 2));
|
||||||
|
chunks.add(ChunkPos.asLong(cx, cz));
|
||||||
|
} finally {
|
||||||
|
areaLock.unlock();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addLightUpdate(int x, int y, int z) {
|
||||||
|
delegate.addLightUpdate(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This method is called "recursively", iterating and removing elements
|
||||||
|
* from the regions linked map. This way, chunks are loaded in batches to avoid
|
||||||
|
* OOMEs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void fixLightingSafe(boolean sky) {
|
||||||
|
this.areaLock.lock();
|
||||||
|
try {
|
||||||
|
if (regions.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LongSet first = regions.removeFirst();
|
||||||
|
fixLighting(first, () -> fixLightingSafe(true));
|
||||||
|
} finally {
|
||||||
|
this.areaLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Processes a set of chunks and runs an action afterwards.
|
||||||
|
* The action is run async, the chunks are partly processed on the main thread
|
||||||
|
* (as required by the server).
|
||||||
|
*/
|
||||||
|
private void fixLighting(LongSet chunks, Runnable andThen) {
|
||||||
|
// convert from long keys to ChunkPos
|
||||||
|
Set<ChunkPos> coords = new HashSet<>();
|
||||||
|
LongIterator iterator = chunks.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
coords.add(new ChunkPos(iterator.nextLong()));
|
||||||
|
}
|
||||||
|
TaskManager.taskManager().task(() -> {
|
||||||
|
// trigger chunk load and apply ticket on main thread
|
||||||
|
List<CompletableFuture<?>> futures = new ArrayList<>();
|
||||||
|
for (ChunkPos pos : coords) {
|
||||||
|
futures.add(serverLevel.getWorld().getChunkAtAsync(pos.x, pos.z)
|
||||||
|
.thenAccept(c -> serverLevel.getChunkSource().addTicketAtLevel(
|
||||||
|
FAWE_TICKET,
|
||||||
|
pos,
|
||||||
|
LIGHT_LEVEL,
|
||||||
|
Unit.INSTANCE
|
||||||
|
))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// collect futures and trigger relight once all chunks are loaded
|
||||||
|
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).thenAccept(v ->
|
||||||
|
invokeRelight(
|
||||||
|
coords,
|
||||||
|
c -> {
|
||||||
|
}, // no callback for single chunks required
|
||||||
|
i -> {
|
||||||
|
if (i != coords.size()) {
|
||||||
|
LOGGER.warn("Processed {} chunks instead of {}", i, coords.size());
|
||||||
|
}
|
||||||
|
// post process chunks on main thread
|
||||||
|
TaskManager.taskManager().task(() -> postProcessChunks(coords));
|
||||||
|
// call callback on our own threads
|
||||||
|
TaskManager.taskManager().async(andThen);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void invokeRelight(
|
||||||
|
Set<ChunkPos> coords,
|
||||||
|
Consumer<ChunkPos> chunkCallback,
|
||||||
|
IntConsumer processCallback
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
int unused = (int) RELIGHT.invokeExact(
|
||||||
|
serverLevel.getChunkSource().getLightEngine(),
|
||||||
|
coords,
|
||||||
|
chunkCallback, // callback per chunk
|
||||||
|
processCallback // callback for all chunks
|
||||||
|
);
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
LOGGER.error("Error occurred on relighting", throwable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allow the server to unload the chunks again.
|
||||||
|
* Also, if chunk packets are sent delayed, we need to do that here
|
||||||
|
*/
|
||||||
|
private void postProcessChunks(Set<ChunkPos> coords) {
|
||||||
|
boolean delay = Settings.settings().LIGHTING.DELAY_PACKET_SENDING;
|
||||||
|
for (ChunkPos pos : coords) {
|
||||||
|
int x = pos.x;
|
||||||
|
int z = pos.z;
|
||||||
|
if (delay) { // we still need to send the block changes of that chunk
|
||||||
|
PaperweightPlatformAdapter.sendChunk(serverLevel, x, z, false);
|
||||||
|
}
|
||||||
|
serverLevel.getChunkSource().removeTicketAtLevel(FAWE_TICKET, pos, LIGHT_LEVEL, Unit.INSTANCE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeLighting() {
|
||||||
|
this.delegate.removeLighting();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fixBlockLighting() {
|
||||||
|
fixLightingSafe(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fixSkyLighting() {
|
||||||
|
fixLightingSafe(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ReentrantLock getLock() {
|
||||||
|
return this.lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFinished() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws Exception {
|
||||||
|
fixLightingSafe(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1;
|
||||||
|
|
||||||
|
import com.fastasyncworldedit.core.extent.processor.lighting.NullRelighter;
|
||||||
|
import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode;
|
||||||
|
import com.fastasyncworldedit.core.extent.processor.lighting.Relighter;
|
||||||
|
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
||||||
|
import com.fastasyncworldedit.core.queue.IQueueChunk;
|
||||||
|
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
||||||
|
import com.sk89q.worldedit.world.World;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.CraftWorld;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public class PaperweightStarlightRelighterFactory implements RelighterFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull
|
||||||
|
Relighter createRelighter(RelightMode relightMode, World world, IQueueExtent<IQueueChunk> queue) {
|
||||||
|
org.bukkit.World w = Bukkit.getWorld(world.getName());
|
||||||
|
if (w == null) {
|
||||||
|
return NullRelighter.INSTANCE;
|
||||||
|
}
|
||||||
|
return new PaperweightStarlightRelighter(((CraftWorld) w).getHandle(), queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,158 @@
|
|||||||
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1.nbt;
|
||||||
|
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.jnbt.LazyCompoundTag;
|
||||||
|
import com.sk89q.jnbt.ListTag;
|
||||||
|
import com.sk89q.jnbt.StringTag;
|
||||||
|
import com.sk89q.jnbt.Tag;
|
||||||
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
|
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
||||||
|
import net.minecraft.nbt.NumericTag;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class PaperweightLazyCompoundTag extends LazyCompoundTag {
|
||||||
|
|
||||||
|
private final Supplier<net.minecraft.nbt.CompoundTag> compoundTagSupplier;
|
||||||
|
private CompoundTag compoundTag;
|
||||||
|
|
||||||
|
public PaperweightLazyCompoundTag(Supplier<net.minecraft.nbt.CompoundTag> compoundTagSupplier) {
|
||||||
|
super(new HashMap<>());
|
||||||
|
this.compoundTagSupplier = compoundTagSupplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PaperweightLazyCompoundTag(net.minecraft.nbt.CompoundTag compoundTag) {
|
||||||
|
this(() -> compoundTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public net.minecraft.nbt.CompoundTag get() {
|
||||||
|
return compoundTagSupplier.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Tag> getValue() {
|
||||||
|
if (compoundTag == null) {
|
||||||
|
compoundTag = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(compoundTagSupplier.get());
|
||||||
|
}
|
||||||
|
return compoundTag.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundBinaryTag asBinaryTag() {
|
||||||
|
getValue();
|
||||||
|
return compoundTag.asBinaryTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsKey(String key) {
|
||||||
|
return compoundTagSupplier.get().contains(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getByteArray(String key) {
|
||||||
|
return compoundTagSupplier.get().getByteArray(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getByte(String key) {
|
||||||
|
return compoundTagSupplier.get().getByte(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getDouble(String key) {
|
||||||
|
return compoundTagSupplier.get().getDouble(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double asDouble(String key) {
|
||||||
|
net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key);
|
||||||
|
if (tag instanceof NumericTag numTag) {
|
||||||
|
return numTag.getAsDouble();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getFloat(String key) {
|
||||||
|
return compoundTagSupplier.get().getFloat(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] getIntArray(String key) {
|
||||||
|
return compoundTagSupplier.get().getIntArray(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInt(String key) {
|
||||||
|
return compoundTagSupplier.get().getInt(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int asInt(String key) {
|
||||||
|
net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key);
|
||||||
|
if (tag instanceof NumericTag numTag) {
|
||||||
|
return numTag.getAsInt();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Tag> getList(String key) {
|
||||||
|
net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key);
|
||||||
|
if (tag instanceof net.minecraft.nbt.ListTag nbtList) {
|
||||||
|
ArrayList<Tag> list = new ArrayList<>();
|
||||||
|
for (net.minecraft.nbt.Tag elem : nbtList) {
|
||||||
|
if (elem instanceof net.minecraft.nbt.CompoundTag compoundTag) {
|
||||||
|
list.add(new PaperweightLazyCompoundTag(compoundTag));
|
||||||
|
} else {
|
||||||
|
list.add(WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(elem));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListTag getListTag(String key) {
|
||||||
|
net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key);
|
||||||
|
if (tag instanceof net.minecraft.nbt.ListTag) {
|
||||||
|
return (ListTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(tag);
|
||||||
|
}
|
||||||
|
return new ListTag(StringTag.class, Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T extends Tag> List<T> getList(String key, Class<T> listType) {
|
||||||
|
ListTag listTag = getListTag(key);
|
||||||
|
if (listTag.getType().equals(listType)) {
|
||||||
|
return (List<T>) listTag.getValue();
|
||||||
|
} else {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long[] getLongArray(String key) {
|
||||||
|
return compoundTagSupplier.get().getLongArray(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLong(String key) {
|
||||||
|
return compoundTagSupplier.get().getLong(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long asLong(String key) {
|
||||||
|
net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key);
|
||||||
|
if (tag instanceof NumericTag numTag) {
|
||||||
|
return numTag.getAsLong();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getShort(String key) {
|
||||||
|
return compoundTagSupplier.get().getShort(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getString(String key) {
|
||||||
|
return compoundTagSupplier.get().getString(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return compoundTagSupplier.get().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,497 @@
|
|||||||
|
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1.regen;
|
||||||
|
|
||||||
|
import com.fastasyncworldedit.bukkit.adapter.Regenerator;
|
||||||
|
import com.fastasyncworldedit.core.Fawe;
|
||||||
|
import com.fastasyncworldedit.core.queue.IChunkCache;
|
||||||
|
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||||
|
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
||||||
|
import com.fastasyncworldedit.core.util.TaskManager;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.mojang.datafixers.util.Either;
|
||||||
|
import com.mojang.serialization.Lifecycle;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R1.PaperweightAdapter;
|
||||||
|
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1.PaperweightGetBlocks;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.util.io.file.SafeFiles;
|
||||||
|
import com.sk89q.worldedit.world.RegenOptions;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.data.BuiltinRegistries;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.level.ServerChunkCache;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ThreadedLevelLightEngine;
|
||||||
|
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.LevelHeightAccessor;
|
||||||
|
import net.minecraft.world.level.LevelSettings;
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||||
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||||
|
import net.minecraft.world.level.chunk.UpgradeData;
|
||||||
|
import net.minecraft.world.level.dimension.LevelStem;
|
||||||
|
import net.minecraft.world.level.levelgen.FlatLevelSource;
|
||||||
|
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||||
|
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||||
|
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||||
|
import net.minecraft.world.level.levelgen.blending.BlendingData;
|
||||||
|
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
|
||||||
|
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||||
|
import net.minecraft.world.level.storage.PrimaryLevelData;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.CraftServer;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.v1_18_R1.generator.CustomChunkGenerator;
|
||||||
|
import org.bukkit.generator.BlockPopulator;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.function.BooleanSupplier;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, LevelChunk, PaperweightRegen.ChunkStatusWrap> {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||||
|
|
||||||
|
private static final Field serverWorldsField;
|
||||||
|
private static final Field paperConfigField;
|
||||||
|
private static final Field flatBedrockField;
|
||||||
|
private static final Field generatorSettingFlatField;
|
||||||
|
private static final Field generatorSettingBaseSupplierField;
|
||||||
|
private static final Field delegateField;
|
||||||
|
private static final Field chunkSourceField;
|
||||||
|
|
||||||
|
//list of chunk stati in correct order without FULL
|
||||||
|
private static final Map<ChunkStatus, Concurrency> chunkStati = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
chunkStati.put(ChunkStatus.EMPTY, Concurrency.FULL); // empty: radius -1, does nothing
|
||||||
|
chunkStati.put(ChunkStatus.STRUCTURE_STARTS, Concurrency.NONE); // structure starts: uses unsynchronized maps
|
||||||
|
chunkStati.put(
|
||||||
|
ChunkStatus.STRUCTURE_REFERENCES,
|
||||||
|
Concurrency.FULL
|
||||||
|
); // structure refs: radius 8, but only writes to current chunk
|
||||||
|
chunkStati.put(ChunkStatus.BIOMES, Concurrency.FULL); // biomes: radius 0
|
||||||
|
chunkStati.put(ChunkStatus.NOISE, Concurrency.RADIUS); // noise: radius 8
|
||||||
|
chunkStati.put(ChunkStatus.SURFACE, Concurrency.NONE); // surface: radius 0, requires NONE
|
||||||
|
chunkStati.put(ChunkStatus.CARVERS, Concurrency.NONE); // carvers: radius 0, but RADIUS and FULL change results
|
||||||
|
chunkStati.put(
|
||||||
|
ChunkStatus.LIQUID_CARVERS,
|
||||||
|
Concurrency.NONE
|
||||||
|
); // liquid carvers: radius 0, but RADIUS and FULL change results
|
||||||
|
chunkStati.put(ChunkStatus.FEATURES, Concurrency.NONE); // features: uses unsynchronized maps
|
||||||
|
chunkStati.put(
|
||||||
|
ChunkStatus.LIGHT,
|
||||||
|
Concurrency.FULL
|
||||||
|
); // light: radius 1, but no writes to other chunks, only current chunk
|
||||||
|
chunkStati.put(ChunkStatus.SPAWN, Concurrency.FULL); // spawn: radius 0
|
||||||
|
chunkStati.put(ChunkStatus.HEIGHTMAPS, Concurrency.FULL); // heightmaps: radius 0
|
||||||
|
|
||||||
|
try {
|
||||||
|
serverWorldsField = CraftServer.class.getDeclaredField("worlds");
|
||||||
|
serverWorldsField.setAccessible(true);
|
||||||
|
|
||||||
|
Field tmpPaperConfigField;
|
||||||
|
Field tmpFlatBedrockField;
|
||||||
|
try { //only present on paper
|
||||||
|
tmpPaperConfigField = Level.class.getDeclaredField("paperConfig");
|
||||||
|
tmpPaperConfigField.setAccessible(true);
|
||||||
|
|
||||||
|
tmpFlatBedrockField = tmpPaperConfigField.getType().getDeclaredField("generateFlatBedrock");
|
||||||
|
tmpFlatBedrockField.setAccessible(true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
tmpPaperConfigField = null;
|
||||||
|
tmpFlatBedrockField = null;
|
||||||
|
}
|
||||||
|
paperConfigField = tmpPaperConfigField;
|
||||||
|
flatBedrockField = tmpFlatBedrockField;
|
||||||
|
|
||||||
|
generatorSettingBaseSupplierField = NoiseBasedChunkGenerator.class.getDeclaredField(Refraction.pickName(
|
||||||
|
"settings", "f"));
|
||||||
|
generatorSettingBaseSupplierField.setAccessible(true);
|
||||||
|
|
||||||
|
generatorSettingFlatField = FlatLevelSource.class.getDeclaredField(Refraction.pickName("settings", "e"));
|
||||||
|
generatorSettingFlatField.setAccessible(true);
|
||||||
|
|
||||||
|
delegateField = CustomChunkGenerator.class.getDeclaredField("delegate");
|
||||||
|
delegateField.setAccessible(true);
|
||||||
|
|
||||||
|
chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "L"));
|
||||||
|
chunkSourceField.setAccessible(true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//runtime
|
||||||
|
private ServerLevel originalServerWorld;
|
||||||
|
private ServerChunkCache originalChunkProvider;
|
||||||
|
private ServerLevel freshWorld;
|
||||||
|
private ServerChunkCache freshChunkProvider;
|
||||||
|
private LevelStorageSource.LevelStorageAccess session;
|
||||||
|
private StructureManager structureManager;
|
||||||
|
private ThreadedLevelLightEngine threadedLevelLightEngine;
|
||||||
|
private ChunkGenerator chunkGenerator;
|
||||||
|
|
||||||
|
private Path tempDir;
|
||||||
|
|
||||||
|
private boolean generateFlatBedrock = false;
|
||||||
|
|
||||||
|
public PaperweightRegen(org.bukkit.World originalBukkitWorld, Region region, Extent target, RegenOptions options) {
|
||||||
|
super(originalBukkitWorld, region, target, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean prepare() {
|
||||||
|
this.originalServerWorld = ((CraftWorld) originalBukkitWorld).getHandle();
|
||||||
|
originalChunkProvider = originalServerWorld.getChunkSource();
|
||||||
|
if (!(originalChunkProvider instanceof ServerChunkCache)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//flat bedrock? (only on paper)
|
||||||
|
if (paperConfigField != null) {
|
||||||
|
try {
|
||||||
|
generateFlatBedrock = flatBedrockField.getBoolean(paperConfigField.get(originalServerWorld));
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
seed = options.getSeed().orElse(originalServerWorld.getSeed());
|
||||||
|
chunkStati.forEach((s, c) -> super.chunkStati.put(new ChunkStatusWrap(s), c));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean initNewWorld() throws Exception {
|
||||||
|
//world folder
|
||||||
|
tempDir = java.nio.file.Files.createTempDirectory("FastAsyncWorldEditWorldGen");
|
||||||
|
|
||||||
|
//prepare for world init (see upstream implementation for reference)
|
||||||
|
org.bukkit.World.Environment environment = originalBukkitWorld.getEnvironment();
|
||||||
|
org.bukkit.generator.ChunkGenerator generator = originalBukkitWorld.getGenerator();
|
||||||
|
LevelStorageSource levelStorageSource = LevelStorageSource.createDefault(tempDir);
|
||||||
|
ResourceKey<LevelStem> levelStemResourceKey = getWorldDimKey(environment);
|
||||||
|
session = levelStorageSource.createAccess("faweregentempworld", levelStemResourceKey);
|
||||||
|
PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData;
|
||||||
|
|
||||||
|
MinecraftServer server = originalServerWorld.getCraftServer().getServer();
|
||||||
|
PrimaryLevelData levelProperties = (PrimaryLevelData) server.getWorldData();
|
||||||
|
WorldGenSettings originalOpts = levelProperties.worldGenSettings();
|
||||||
|
WorldGenSettings newOpts = options.getSeed().isPresent()
|
||||||
|
? PaperweightAdapter.replaceSeed(originalServerWorld, seed, originalOpts)
|
||||||
|
: originalOpts;
|
||||||
|
LevelSettings newWorldSettings = new LevelSettings(
|
||||||
|
"faweregentempworld",
|
||||||
|
originalWorldData.settings.gameType(),
|
||||||
|
originalWorldData.settings.hardcore(),
|
||||||
|
originalWorldData.settings.difficulty(),
|
||||||
|
originalWorldData.settings.allowCommands(),
|
||||||
|
originalWorldData.settings.gameRules(),
|
||||||
|
originalWorldData.settings.getDataPackConfig()
|
||||||
|
);
|
||||||
|
PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, Lifecycle.stable());
|
||||||
|
|
||||||
|
//init world
|
||||||
|
freshWorld = Fawe.instance().getQueueHandler().sync((Supplier<ServerLevel>) () -> new ServerLevel(
|
||||||
|
server,
|
||||||
|
server.executor,
|
||||||
|
session,
|
||||||
|
newWorldData,
|
||||||
|
originalServerWorld.dimension(),
|
||||||
|
originalServerWorld.dimensionType(),
|
||||||
|
new RegenNoOpWorldLoadListener(),
|
||||||
|
// placeholder. Required for new ChunkProviderServer, but we create and then set it later
|
||||||
|
newOpts.dimensions().get(levelStemResourceKey).generator(),
|
||||||
|
originalServerWorld.isDebug(),
|
||||||
|
seed,
|
||||||
|
ImmutableList.of(),
|
||||||
|
false,
|
||||||
|
environment,
|
||||||
|
generator,
|
||||||
|
originalBukkitWorld.getBiomeProvider()
|
||||||
|
) {
|
||||||
|
private final Biome singleBiome = options.hasBiomeType() ? BuiltinRegistries.BIOME.get(ResourceLocation.tryParse(
|
||||||
|
options
|
||||||
|
.getBiomeType()
|
||||||
|
.getId())) : null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick(BooleanSupplier shouldKeepTicking) { //no ticking
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Biome getUncachedNoiseBiome(int biomeX, int biomeY, int biomeZ) {
|
||||||
|
if (options.hasBiomeType()) {
|
||||||
|
return singleBiome;
|
||||||
|
}
|
||||||
|
return PaperweightRegen.this.chunkGenerator.getBiomeSource().getNoiseBiome(biomeX, biomeY, biomeZ,
|
||||||
|
PaperweightRegen.this.chunkGenerator.climateSampler()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}).get();
|
||||||
|
freshWorld.noSave = true;
|
||||||
|
removeWorldFromWorldsMap();
|
||||||
|
newWorldData.checkName(originalServerWorld.serverLevelData.getLevelName()); //rename to original world name
|
||||||
|
if (paperConfigField != null) {
|
||||||
|
paperConfigField.set(freshWorld, originalServerWorld.paperConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
//generator
|
||||||
|
if (originalChunkProvider.getGenerator() instanceof FlatLevelSource flatLevelSource) {
|
||||||
|
FlatLevelGeneratorSettings generatorSettingFlat = flatLevelSource.settings();
|
||||||
|
chunkGenerator = new FlatLevelSource(generatorSettingFlat);
|
||||||
|
} else if (originalChunkProvider.getGenerator() instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) {
|
||||||
|
Supplier<NoiseGeneratorSettings> generatorSettingBaseSupplier = (Supplier<NoiseGeneratorSettings>) generatorSettingBaseSupplierField
|
||||||
|
.get(originalChunkProvider.getGenerator());
|
||||||
|
BiomeSource biomeSource = originalChunkProvider.getGenerator().getBiomeSource();
|
||||||
|
chunkGenerator = new NoiseBasedChunkGenerator(noiseBasedChunkGenerator.noises, biomeSource, seed,
|
||||||
|
generatorSettingBaseSupplier
|
||||||
|
);
|
||||||
|
} else if (originalChunkProvider.getGenerator() instanceof CustomChunkGenerator customChunkGenerator) {
|
||||||
|
chunkGenerator = customChunkGenerator.delegate;
|
||||||
|
} else {
|
||||||
|
LOGGER.error("Unsupported generator type {}", originalChunkProvider.getGenerator().getClass().getName());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (generator != null) {
|
||||||
|
chunkGenerator = new CustomChunkGenerator(freshWorld, chunkGenerator, generator);
|
||||||
|
generateConcurrent = generator.isParallelCapable();
|
||||||
|
}
|
||||||
|
|
||||||
|
freshChunkProvider = new ServerChunkCache(
|
||||||
|
freshWorld,
|
||||||
|
session,
|
||||||
|
server.getFixerUpper(),
|
||||||
|
server.getStructureManager(),
|
||||||
|
server.executor,
|
||||||
|
chunkGenerator,
|
||||||
|
freshWorld.spigotConfig.viewDistance,
|
||||||
|
freshWorld.spigotConfig.simulationDistance,
|
||||||
|
server.forceSynchronousWrites(),
|
||||||
|
new RegenNoOpWorldLoadListener(),
|
||||||
|
(chunkCoordIntPair, state) -> {
|
||||||
|
},
|
||||||
|
() -> server.overworld().getDataStorage()
|
||||||
|
) {
|
||||||
|
// redirect to LevelChunks created in #createChunks
|
||||||
|
@Override
|
||||||
|
public ChunkAccess getChunk(int x, int z, ChunkStatus chunkstatus, boolean flag) {
|
||||||
|
return getChunkAt(x, z);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ReflectionUtils.unsafeSet(chunkSourceField, freshWorld, freshChunkProvider);
|
||||||
|
//let's start then
|
||||||
|
structureManager = server.getStructureManager();
|
||||||
|
threadedLevelLightEngine = freshChunkProvider.getLightEngine();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void cleanup() {
|
||||||
|
try {
|
||||||
|
session.close();
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
//shutdown chunk provider
|
||||||
|
try {
|
||||||
|
Fawe.instance().getQueueHandler().sync(() -> {
|
||||||
|
try {
|
||||||
|
freshChunkProvider.close(false);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
//remove world from server
|
||||||
|
try {
|
||||||
|
Fawe.instance().getQueueHandler().sync(this::removeWorldFromWorldsMap);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete directory
|
||||||
|
try {
|
||||||
|
SafeFiles.tryHardToDeleteDir(tempDir);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ProtoChunk createProtoChunk(int x, int z) {
|
||||||
|
return new FastProtoChunk(new ChunkPos(x, z), UpgradeData.EMPTY, freshWorld,
|
||||||
|
this.freshWorld.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected LevelChunk createChunk(ProtoChunk protoChunk) {
|
||||||
|
return new LevelChunk(
|
||||||
|
freshWorld,
|
||||||
|
protoChunk,
|
||||||
|
null // we don't want to add entities
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ChunkStatusWrap getFullChunkStatus() {
|
||||||
|
return new ChunkStatusWrap(ChunkStatus.FULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<BlockPopulator> getBlockPopulators() {
|
||||||
|
return originalServerWorld.getWorld().getPopulators();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blockPopulator) {
|
||||||
|
// BlockPopulator#populate has to be called synchronously for TileEntity access
|
||||||
|
TaskManager.taskManager().task(() -> blockPopulator.populate(freshWorld.getWorld(), random, levelChunk.getBukkitChunk()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IChunkCache<IChunkGet> initSourceQueueCache() {
|
||||||
|
return (chunkX, chunkZ) -> new PaperweightGetBlocks(freshWorld, chunkX, chunkZ) {
|
||||||
|
@Override
|
||||||
|
public LevelChunk ensureLoaded(ServerLevel nmsWorld, int x, int z) {
|
||||||
|
return getChunkAt(x, z);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//util
|
||||||
|
private void removeWorldFromWorldsMap() {
|
||||||
|
Fawe.instance().getQueueHandler().sync(() -> {
|
||||||
|
try {
|
||||||
|
Map<String, org.bukkit.World> map = (Map<String, org.bukkit.World>) serverWorldsField.get(Bukkit.getServer());
|
||||||
|
map.remove("faweregentempworld");
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResourceKey<LevelStem> getWorldDimKey(org.bukkit.World.Environment env) {
|
||||||
|
return switch (env) {
|
||||||
|
case NETHER -> LevelStem.NETHER;
|
||||||
|
case THE_END -> LevelStem.END;
|
||||||
|
default -> LevelStem.OVERWORLD;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class RegenNoOpWorldLoadListener implements ChunkProgressListener {
|
||||||
|
|
||||||
|
private RegenNoOpWorldLoadListener() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSpawnPos(ChunkPos spawnPos) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStatusChange(ChunkPos pos, @Nullable ChunkStatus status) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Paper only(?) @Override
|
||||||
|
public void setChunkRadius(int radius) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FastProtoChunk extends ProtoChunk {
|
||||||
|
|
||||||
|
public FastProtoChunk(
|
||||||
|
final ChunkPos pos,
|
||||||
|
final UpgradeData upgradeData,
|
||||||
|
final LevelHeightAccessor world,
|
||||||
|
final Registry<Biome> biomeRegistry,
|
||||||
|
@Nullable final BlendingData blendingData
|
||||||
|
) {
|
||||||
|
super(pos, upgradeData, world, biomeRegistry, blendingData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// avoid warning on paper
|
||||||
|
|
||||||
|
// compatibility with spigot
|
||||||
|
|
||||||
|
public boolean generateFlatBedrock() {
|
||||||
|
return generateFlatBedrock;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no one will ever see the entities!
|
||||||
|
@Override
|
||||||
|
public List<CompoundTag> getEntities() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected class ChunkStatusWrap extends ChunkStatusWrapper<ChunkAccess> {
|
||||||
|
|
||||||
|
private final ChunkStatus chunkStatus;
|
||||||
|
|
||||||
|
public ChunkStatusWrap(ChunkStatus chunkStatus) {
|
||||||
|
this.chunkStatus = chunkStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int requiredNeighborChunkRadius() {
|
||||||
|
return chunkStatus.getRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return chunkStatus.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<?> processChunk(Long xz, List<ChunkAccess> accessibleChunks) {
|
||||||
|
return chunkStatus.generate(
|
||||||
|
Runnable::run, // TODO revisit, we might profit from this somehow?
|
||||||
|
freshWorld,
|
||||||
|
chunkGenerator,
|
||||||
|
structureManager,
|
||||||
|
threadedLevelLightEngine,
|
||||||
|
c -> CompletableFuture.completedFuture(Either.left(c)),
|
||||||
|
accessibleChunks,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Binäre Datei nicht angezeigt.
@ -42,12 +42,6 @@ repositories {
|
|||||||
flatDir { dir(File("src/main/resources")) }
|
flatDir { dir(File("src/main/resources")) }
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations.all {
|
|
||||||
resolutionStrategy {
|
|
||||||
force("com.google.guava:guava:21.0")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val localImplementation = configurations.create("localImplementation") {
|
val localImplementation = configurations.create("localImplementation") {
|
||||||
description = "Dependencies used locally, but provided by the runtime Bukkit implementation"
|
description = "Dependencies used locally, but provided by the runtime Bukkit implementation"
|
||||||
isCanBeConsumed = false
|
isCanBeConsumed = false
|
||||||
@ -108,7 +102,6 @@ dependencies {
|
|||||||
compileOnly(libs.protocollib) { isTransitive = false }
|
compileOnly(libs.protocollib) { isTransitive = false }
|
||||||
compileOnly(libs.plotsquaredV6Bukkit) { isTransitive = false }
|
compileOnly(libs.plotsquaredV6Bukkit) { isTransitive = false }
|
||||||
compileOnly(libs.plotsquaredV6Core) { isTransitive = false }
|
compileOnly(libs.plotsquaredV6Core) { isTransitive = false }
|
||||||
compileOnly(libs.plotsquaredV4) { isTransitive = false }
|
|
||||||
|
|
||||||
// Third party
|
// Third party
|
||||||
compileOnly(libs.flowmath) {
|
compileOnly(libs.flowmath) {
|
||||||
@ -187,7 +180,7 @@ tasks.named<ShadowJar>("shadowJar") {
|
|||||||
include(dependency("dev.notmyfault.serverlib:ServerLib:2.3.1"))
|
include(dependency("dev.notmyfault.serverlib:ServerLib:2.3.1"))
|
||||||
}
|
}
|
||||||
relocate("com.intellectualsites.paster", "com.fastasyncworldedit.paster") {
|
relocate("com.intellectualsites.paster", "com.fastasyncworldedit.paster") {
|
||||||
include(dependency("com.intellectualsites.paster:Paster:1.1.1"))
|
include(dependency("com.intellectualsites.paster:Paster:1.1.3"))
|
||||||
}
|
}
|
||||||
relocate("org.lz4", "com.fastasyncworldedit.core.lz4") {
|
relocate("org.lz4", "com.fastasyncworldedit.core.lz4") {
|
||||||
include(dependency("org.lz4:lz4-java:1.8.0"))
|
include(dependency("org.lz4:lz4-java:1.8.0"))
|
||||||
|
@ -68,7 +68,6 @@ public class FaweBukkit implements IFawe, Listener {
|
|||||||
public FaweBukkit(Plugin plugin) {
|
public FaweBukkit(Plugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
try {
|
try {
|
||||||
Settings.IMP.TICK_LIMITER.ENABLED = !Bukkit.hasWhitelist();
|
|
||||||
Fawe.set(this);
|
Fawe.set(this);
|
||||||
Fawe.setupInjector();
|
Fawe.setupInjector();
|
||||||
try {
|
try {
|
||||||
@ -76,7 +75,7 @@ public class FaweBukkit implements IFawe, Listener {
|
|||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
LOGGER.error("Brush Listener Failed", e);
|
LOGGER.error("Brush Listener Failed", e);
|
||||||
}
|
}
|
||||||
if (PaperLib.isPaper() && Settings.IMP.EXPERIMENTAL.DYNAMIC_CHUNK_RENDERING > 1) {
|
if (PaperLib.isPaper() && Settings.settings().EXPERIMENTAL.DYNAMIC_CHUNK_RENDERING > 1) {
|
||||||
new RenderListener(plugin);
|
new RenderListener(plugin);
|
||||||
}
|
}
|
||||||
} catch (final Throwable e) {
|
} catch (final Throwable e) {
|
||||||
@ -84,17 +83,19 @@ public class FaweBukkit implements IFawe, Listener {
|
|||||||
Bukkit.getServer().shutdown();
|
Bukkit.getServer().shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
chunksStretched = new MinecraftVersion().isEqualOrHigher(MinecraftVersion.NETHER);
|
MinecraftVersion version = new MinecraftVersion();
|
||||||
|
|
||||||
|
chunksStretched = version.isEqualOrHigherThan(MinecraftVersion.NETHER);
|
||||||
|
|
||||||
platformAdapter = new NMSAdapter();
|
platformAdapter = new NMSAdapter();
|
||||||
|
|
||||||
//PlotSquared support is limited to Spigot/Paper as of 02/20/2020
|
//PlotSquared support is limited to Spigot/Paper as of 02/20/2020
|
||||||
TaskManager.IMP.later(this::setupPlotSquared, 0);
|
TaskManager.taskManager().later(this::setupPlotSquared, 0);
|
||||||
|
|
||||||
// Registered delayed Event Listeners
|
// Registered delayed Event Listeners
|
||||||
TaskManager.IMP.task(() -> {
|
TaskManager.taskManager().task(() -> {
|
||||||
// Fix for ProtocolSupport
|
// Fix for ProtocolSupport
|
||||||
Settings.IMP.PROTOCOL_SUPPORT_FIX =
|
Settings.settings().PROTOCOL_SUPPORT_FIX =
|
||||||
Bukkit.getPluginManager().isPluginEnabled("ProtocolSupport");
|
Bukkit.getPluginManager().isPluginEnabled("ProtocolSupport");
|
||||||
|
|
||||||
// This class
|
// This class
|
||||||
@ -103,6 +104,11 @@ public class FaweBukkit implements IFawe, Listener {
|
|||||||
// The tick limiter
|
// The tick limiter
|
||||||
new ChunkListener9();
|
new ChunkListener9();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Warn if small-edits are enabled with extended world heights
|
||||||
|
if (version.isEqualOrHigherThan(MinecraftVersion.CAVES_18) && Settings.settings().HISTORY.SMALL_EDITS) {
|
||||||
|
LOGGER.warn("Small-edits enabled (maximum y range of 0 -> 256) with 1.18 world heights. Are you sure?");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -141,7 +147,7 @@ public class FaweBukkit implements IFawe, Listener {
|
|||||||
try {
|
try {
|
||||||
this.itemUtil = tmp = new ItemUtil();
|
this.itemUtil = tmp = new ItemUtil();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Settings.IMP.EXPERIMENTAL.PERSISTENT_BRUSHES = false;
|
Settings.settings().EXPERIMENTAL.PERSISTENT_BRUSHES = false;
|
||||||
LOGGER.error("Persistent Brushes Failed", e);
|
LOGGER.error("Persistent Brushes Failed", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -310,14 +316,12 @@ public class FaweBukkit implements IFawe, Listener {
|
|||||||
if (plotSquared == null) {
|
if (plotSquared == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (plotSquared.getClass().getPackage().toString().contains("intellectualsites")) {
|
if (PlotSquared.get().getVersion().version[0] == 6) {
|
||||||
WEManager.IMP.addManager(new com.fastasyncworldedit.bukkit.regions.plotsquaredv4.PlotSquaredFeature());
|
WEManager.weManager().addManager(new com.fastasyncworldedit.bukkit.regions.plotsquared.PlotSquaredFeature());
|
||||||
LOGGER.info("Plugin 'PlotSquared' found. Using it now.");
|
LOGGER.info("Plugin 'PlotSquared' v6 found. Using it now.");
|
||||||
} else if (PlotSquared.get().getVersion().version[0] == 6) {
|
|
||||||
WEManager.IMP.addManager(new com.fastasyncworldedit.bukkit.regions.plotsquared.PlotSquaredFeature());
|
|
||||||
LOGGER.info("Plugin 'PlotSquared' found. Using it now.");
|
|
||||||
} else {
|
} else {
|
||||||
LOGGER.error("Incompatible version of PlotSquared found. Please use PlotSquared v6.");
|
LOGGER.error("Incompatible version of PlotSquared found. Please use PlotSquared v6.");
|
||||||
|
LOGGER.info("https://www.spigotmc.org/resources/77506/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,7 +389,7 @@ public interface IBukkitAdapter {
|
|||||||
* @return list of {@link org.bukkit.entity.Entity}
|
* @return list of {@link org.bukkit.entity.Entity}
|
||||||
*/
|
*/
|
||||||
default List<org.bukkit.entity.Entity> getEntities(org.bukkit.World world) {
|
default List<org.bukkit.entity.Entity> getEntities(org.bukkit.World world) {
|
||||||
return TaskManager.IMP.sync(world::getEntities);
|
return TaskManager.taskManager().sync(world::getEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ public interface IDelegateBukkitImplAdapter<T> extends BukkitImplAdapter<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default BaseBlock getBlock(Location location) {
|
default BlockState getBlock(Location location) {
|
||||||
return getParent().getBlock(location);
|
return getParent().getBlock(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import com.fastasyncworldedit.core.FAWEPlatformAdapterImpl;
|
|||||||
import com.fastasyncworldedit.core.configuration.Settings;
|
import com.fastasyncworldedit.core.configuration.Settings;
|
||||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||||
import com.fastasyncworldedit.core.util.MathMan;
|
import com.fastasyncworldedit.core.util.MathMan;
|
||||||
import com.fastasyncworldedit.core.world.block.BlockID;
|
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
@ -24,8 +23,8 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl {
|
|||||||
int num_palette = 0;
|
int num_palette = 0;
|
||||||
for (int i = 0; i < 4096; i++) {
|
for (int i = 0; i < 4096; i++) {
|
||||||
char ordinal = set[i];
|
char ordinal = set[i];
|
||||||
if (ordinal == BlockID.__RESERVED__) {
|
if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) {
|
||||||
ordinal = BlockID.AIR;
|
ordinal = BlockTypesCache.ReservedIDs.AIR;
|
||||||
}
|
}
|
||||||
int palette = blockToPalette[ordinal];
|
int palette = blockToPalette[ordinal];
|
||||||
if (palette == Integer.MAX_VALUE) {
|
if (palette == Integer.MAX_VALUE) {
|
||||||
@ -43,17 +42,15 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl {
|
|||||||
}
|
}
|
||||||
System.arraycopy(adapter.getOrdinalToIbdID(), 0, blockToPalette, 0, adapter.getOrdinalToIbdID().length);
|
System.arraycopy(adapter.getOrdinalToIbdID(), 0, blockToPalette, 0, adapter.getOrdinalToIbdID().length);
|
||||||
}
|
}
|
||||||
char lastOrdinal = BlockID.__RESERVED__;
|
char lastOrdinal = 0;
|
||||||
boolean lastticking = false;
|
boolean lastticking = false;
|
||||||
boolean tick_placed = Settings.IMP.EXPERIMENTAL.ALLOW_TICK_PLACED;
|
boolean tick_placed = Settings.settings().EXPERIMENTAL.ALLOW_TICK_PLACED;
|
||||||
for (int i = 0; i < 4096; i++) {
|
for (int i = 0; i < 4096; i++) {
|
||||||
char ordinal = set[i];
|
char ordinal = set[i];
|
||||||
switch (ordinal) {
|
switch (ordinal) {
|
||||||
case BlockID.__RESERVED__:
|
case BlockTypesCache.ReservedIDs.__RESERVED__:
|
||||||
ordinal = BlockID.AIR;
|
ordinal = BlockTypesCache.ReservedIDs.AIR;
|
||||||
case BlockID.AIR:
|
case BlockTypesCache.ReservedIDs.AIR, BlockTypesCache.ReservedIDs.CAVE_AIR, BlockTypesCache.ReservedIDs.VOID_AIR:
|
||||||
case BlockID.CAVE_AIR:
|
|
||||||
case BlockID.VOID_AIR:
|
|
||||||
air++;
|
air++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -95,13 +92,13 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl {
|
|||||||
char[] getArr = null;
|
char[] getArr = null;
|
||||||
for (int i = 0; i < 4096; i++) {
|
for (int i = 0; i < 4096; i++) {
|
||||||
char ordinal = set[i];
|
char ordinal = set[i];
|
||||||
if (ordinal == BlockID.__RESERVED__) {
|
if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) {
|
||||||
if (getArr == null) {
|
if (getArr == null) {
|
||||||
getArr = get.apply(layer);
|
getArr = get.apply(layer);
|
||||||
}
|
}
|
||||||
ordinal = getArr[i];
|
ordinal = getArr[i];
|
||||||
if (ordinal == BlockID.__RESERVED__) {
|
if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) {
|
||||||
ordinal = BlockID.AIR;
|
ordinal = BlockTypesCache.ReservedIDs.AIR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int palette = blockToPalette[ordinal];
|
int palette = blockToPalette[ordinal];
|
||||||
@ -120,26 +117,23 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl {
|
|||||||
}
|
}
|
||||||
System.arraycopy(adapter.getOrdinalToIbdID(), 0, blockToPalette, 0, adapter.getOrdinalToIbdID().length);
|
System.arraycopy(adapter.getOrdinalToIbdID(), 0, blockToPalette, 0, adapter.getOrdinalToIbdID().length);
|
||||||
}
|
}
|
||||||
char lastOrdinal = BlockID.__RESERVED__;
|
char lastOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__;
|
||||||
boolean lastticking = false;
|
boolean lastticking = false;
|
||||||
boolean tick_placed = Settings.IMP.EXPERIMENTAL.ALLOW_TICK_PLACED;
|
boolean tick_placed = Settings.settings().EXPERIMENTAL.ALLOW_TICK_PLACED;
|
||||||
boolean tick_existing = Settings.IMP.EXPERIMENTAL.ALLOW_TICK_EXISTING;
|
boolean tick_existing = Settings.settings().EXPERIMENTAL.ALLOW_TICK_EXISTING;
|
||||||
for (int i = 0; i < 4096; i++) {
|
for (int i = 0; i < 4096; i++) {
|
||||||
char ordinal = set[i];
|
char ordinal = set[i];
|
||||||
switch (ordinal) {
|
switch (ordinal) {
|
||||||
case BlockID.__RESERVED__: {
|
case BlockTypesCache.ReservedIDs.__RESERVED__ -> {
|
||||||
if (getArr == null) {
|
if (getArr == null) {
|
||||||
getArr = get.apply(layer);
|
getArr = get.apply(layer);
|
||||||
}
|
}
|
||||||
ordinal = getArr[i];
|
set[i] = switch (ordinal = getArr[i]) {
|
||||||
switch (ordinal) {
|
case BlockTypesCache.ReservedIDs.__RESERVED__:
|
||||||
case BlockID.__RESERVED__:
|
ordinal = BlockTypesCache.ReservedIDs.AIR;
|
||||||
ordinal = BlockID.AIR;
|
case BlockTypesCache.ReservedIDs.AIR, BlockTypesCache.ReservedIDs.CAVE_AIR, BlockTypesCache.ReservedIDs.VOID_AIR:
|
||||||
case BlockID.AIR:
|
|
||||||
case BlockID.CAVE_AIR:
|
|
||||||
case BlockID.VOID_AIR:
|
|
||||||
air++;
|
air++;
|
||||||
break;
|
yield ordinal;
|
||||||
default:
|
default:
|
||||||
if (!fastmode && !tick_placed && tick_existing) {
|
if (!fastmode && !tick_placed && tick_existing) {
|
||||||
boolean ticking;
|
boolean ticking;
|
||||||
@ -152,23 +146,19 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl {
|
|||||||
}
|
}
|
||||||
if (ticking) {
|
if (ticking) {
|
||||||
BlockState state = BlockState.getFromOrdinal(ordinal);
|
BlockState state = BlockState.getFromOrdinal(ordinal);
|
||||||
ticking_blocks
|
ticking_blocks.put(BlockVector3.at(i & 15, (i >> 8) & 15, (i >> 4) & 15),
|
||||||
.put(
|
WorldEditPlugin
|
||||||
BlockVector3.at(i & 15, (i >> 8) & 15, (i >> 4) & 15),
|
.getInstance()
|
||||||
WorldEditPlugin.getInstance().getBukkitImplAdapter()
|
.getBukkitImplAdapter()
|
||||||
.getInternalBlockStateId(state).orElse(0)
|
.getInternalBlockStateId(state)
|
||||||
);
|
.orElse(0)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
yield ordinal;
|
||||||
set[i] = ordinal;
|
};
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case BlockID.AIR:
|
case BlockTypesCache.ReservedIDs.AIR, BlockTypesCache.ReservedIDs.CAVE_AIR, BlockTypesCache.ReservedIDs.VOID_AIR -> air++;
|
||||||
case BlockID.CAVE_AIR:
|
|
||||||
case BlockID.VOID_AIR:
|
|
||||||
air++;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (!fastmode && tick_placed) {
|
if (!fastmode && tick_placed) {
|
||||||
boolean ticking;
|
boolean ticking;
|
||||||
|
@ -18,7 +18,7 @@ public class NMSRelighterFactory implements RelighterFactory {
|
|||||||
Relighter createRelighter(RelightMode relightMode, World world, IQueueExtent<IQueueChunk> queue) {
|
Relighter createRelighter(RelightMode relightMode, World world, IQueueExtent<IQueueChunk> queue) {
|
||||||
return new NMSRelighter(
|
return new NMSRelighter(
|
||||||
queue,
|
queue,
|
||||||
relightMode != null ? relightMode : RelightMode.valueOf(Settings.IMP.LIGHTING.MODE)
|
relightMode != null ? relightMode : RelightMode.valueOf(Settings.settings().LIGHTING.MODE)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,10 @@ import com.fastasyncworldedit.core.queue.IChunkCache;
|
|||||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||||
import com.fastasyncworldedit.core.queue.implementation.SingleThreadQueueExtent;
|
import com.fastasyncworldedit.core.queue.implementation.SingleThreadQueueExtent;
|
||||||
import com.fastasyncworldedit.core.util.MathMan;
|
import com.fastasyncworldedit.core.util.MathMan;
|
||||||
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
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.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
@ -32,6 +35,7 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -151,7 +155,10 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
|||||||
private boolean generate() throws Exception {
|
private boolean generate() throws Exception {
|
||||||
if (generateConcurrent) {
|
if (generateConcurrent) {
|
||||||
//Using concurrent chunk generation
|
//Using concurrent chunk generation
|
||||||
executor = Executors.newFixedThreadPool(Settings.IMP.QUEUE.PARALLEL_THREADS);
|
executor = Executors.newFixedThreadPool(Settings.settings().QUEUE.PARALLEL_THREADS, new ThreadFactoryBuilder()
|
||||||
|
.setNameFormat("fawe-regen-%d")
|
||||||
|
.build()
|
||||||
|
);
|
||||||
} // else using sequential chunk generation, concurrent not supported
|
} // else using sequential chunk generation, concurrent not supported
|
||||||
|
|
||||||
//TODO: can we get that required radius down without affecting chunk generation (e.g. strucures, features, ...)?
|
//TODO: can we get that required radius down without affecting chunk generation (e.g. strucures, features, ...)?
|
||||||
@ -283,19 +290,52 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
|||||||
|
|
||||||
private void copyToWorld() {
|
private void copyToWorld() {
|
||||||
//Setting Blocks
|
//Setting Blocks
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
boolean genbiomes = options.shouldRegenBiomes();
|
boolean genbiomes = options.shouldRegenBiomes();
|
||||||
boolean hasBiome = options.hasBiomeType();
|
boolean hasBiome = options.hasBiomeType();
|
||||||
BiomeType biome = options.getBiomeType();
|
BiomeType biome = options.getBiomeType();
|
||||||
for (BlockVector3 vec : region) {
|
if (!genbiomes && !hasBiome) {
|
||||||
BaseBlock block = source.getFullBlock(vec);
|
target.setBlocks(region, new PlacementPattern());
|
||||||
target.setBlock(vec, block);
|
|
||||||
if (hasBiome) {
|
|
||||||
target.setBiome(vec, biome);
|
|
||||||
} else if (genbiomes) {
|
|
||||||
target.setBiome(vec, source.getBiome(vec));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (hasBiome) {
|
||||||
|
target.setBlocks(region, new WithBiomePlacementPattern(ignored -> biome));
|
||||||
|
} else if (genbiomes) {
|
||||||
|
target.setBlocks(region, new WithBiomePlacementPattern(vec -> source.getBiome(vec)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PlacementPattern implements Pattern {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock applyBlock(final BlockVector3 position) {
|
||||||
|
return source.getFullBlock(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(final Extent extent, final BlockVector3 get, final BlockVector3 set) throws WorldEditException {
|
||||||
|
return extent.setBlock(set.getX(), set.getY(), set.getZ(), source.getFullBlock(get.getX(), get.getY(), get.getZ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class WithBiomePlacementPattern implements Pattern {
|
||||||
|
|
||||||
|
private final Function<BlockVector3, BiomeType> biomeGetter;
|
||||||
|
|
||||||
|
private WithBiomePlacementPattern(final Function<BlockVector3, BiomeType> biomeGetter) {
|
||||||
|
this.biomeGetter = biomeGetter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock applyBlock(final BlockVector3 position) {
|
||||||
|
return source.getFullBlock(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(final Extent extent, final BlockVector3 get, final BlockVector3 set) throws WorldEditException {
|
||||||
|
return extent.setBlock(set.getX(), set.getY(), set.getZ(), source.getFullBlock(get.getX(), get.getY(), get.getZ()))
|
||||||
|
&& extent.setBiome(set.getX(), set.getY(), set.getZ(), biomeGetter.apply(get));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//functions to be implemented by sub class
|
//functions to be implemented by sub class
|
||||||
|
@ -45,20 +45,25 @@ import org.bukkit.plugin.Plugin;
|
|||||||
import org.bukkit.plugin.PluginManager;
|
import org.bukkit.plugin.PluginManager;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated FAWE is not necessarily the tool you want to use to limit certain tick actions, e.g. fireworks or elytra flying.
|
||||||
|
* The code is untouched since the 1.12 era and there is no guarantee that it will work or will be maintained in the future.
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "2.0.0")
|
||||||
public abstract class ChunkListener implements Listener {
|
public abstract class ChunkListener implements Listener {
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||||
protected int rateLimit = 0;
|
protected int rateLimit = 0;
|
||||||
protected Location lastCancelPos;
|
protected Location lastCancelPos;
|
||||||
private final int[] badLimit = new int[]{Settings.IMP.TICK_LIMITER.PHYSICS_MS,
|
private final int[] badLimit = new int[]{Settings.settings().TICK_LIMITER.PHYSICS_MS,
|
||||||
Settings.IMP.TICK_LIMITER.FALLING, Settings.IMP.TICK_LIMITER.ITEMS};
|
Settings.settings().TICK_LIMITER.FALLING, Settings.settings().TICK_LIMITER.ITEMS};
|
||||||
|
|
||||||
public ChunkListener() {
|
public ChunkListener() {
|
||||||
if (Settings.IMP.TICK_LIMITER.ENABLED) {
|
if (Settings.settings().TICK_LIMITER.ENABLED) {
|
||||||
PluginManager plm = Bukkit.getPluginManager();
|
PluginManager plm = Bukkit.getPluginManager();
|
||||||
Plugin plugin = Fawe.<FaweBukkit>imp().getPlugin();
|
Plugin plugin = Fawe.<FaweBukkit>platform().getPlugin();
|
||||||
plm.registerEvents(this, plugin);
|
plm.registerEvents(this, plugin);
|
||||||
TaskManager.IMP.repeat(() -> {
|
TaskManager.taskManager().repeat(() -> {
|
||||||
Location tmpLoc = lastCancelPos;
|
Location tmpLoc = lastCancelPos;
|
||||||
if (tmpLoc != null) {
|
if (tmpLoc != null) {
|
||||||
LOGGER.info("[FAWE Tick Limiter] Detected and cancelled physics lag source at {}", tmpLoc);
|
LOGGER.info("[FAWE Tick Limiter] Detected and cancelled physics lag source at {}", tmpLoc);
|
||||||
@ -80,7 +85,7 @@ public abstract class ChunkListener implements Listener {
|
|||||||
counter.put(key, badLimit);
|
counter.put(key, badLimit);
|
||||||
}
|
}
|
||||||
badChunks.clear();
|
badChunks.clear();
|
||||||
}, Settings.IMP.TICK_LIMITER.INTERVAL);
|
}, Settings.settings().TICK_LIMITER.INTERVAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +93,15 @@ public abstract class ChunkListener implements Listener {
|
|||||||
|
|
||||||
protected abstract StackTraceElement getElement(Exception ex, int index);
|
protected abstract StackTraceElement getElement(Exception ex, int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated see {@link com.fastasyncworldedit.bukkit.listener.ChunkListener} for an explanation of the deprecation
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "2.0.0")
|
||||||
public static boolean physicsFreeze = false;
|
public static boolean physicsFreeze = false;
|
||||||
|
/**
|
||||||
|
* @deprecated see {@link com.fastasyncworldedit.bukkit.listener.ChunkListener} for an explanation of the deprecation
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "2.0.0")
|
||||||
public static boolean itemFreeze = false;
|
public static boolean itemFreeze = false;
|
||||||
|
|
||||||
protected final Long2ObjectOpenHashMap<Boolean> badChunks = new Long2ObjectOpenHashMap<>();
|
protected final Long2ObjectOpenHashMap<Boolean> badChunks = new Long2ObjectOpenHashMap<>();
|
||||||
@ -97,6 +110,10 @@ public abstract class ChunkListener implements Listener {
|
|||||||
private int lastZ = Integer.MIN_VALUE;
|
private int lastZ = Integer.MIN_VALUE;
|
||||||
private int[] lastCount;
|
private int[] lastCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated see {@link com.fastasyncworldedit.bukkit.listener.ChunkListener} for an explanation of the deprecation
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "2.0.0")
|
||||||
public int[] getCount(int cx, int cz) {
|
public int[] getCount(int cx, int cz) {
|
||||||
if (lastX == cx && lastZ == cz) {
|
if (lastX == cx && lastZ == cz) {
|
||||||
return lastCount;
|
return lastCount;
|
||||||
@ -112,6 +129,10 @@ public abstract class ChunkListener implements Listener {
|
|||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated see {@link com.fastasyncworldedit.bukkit.listener.ChunkListener} for an explanation of the deprecation
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "2.0.0")
|
||||||
public void cleanup(Chunk chunk) {
|
public void cleanup(Chunk chunk) {
|
||||||
for (Entity entity : chunk.getEntities()) {
|
for (Entity entity : chunk.getEntities()) {
|
||||||
if (entity.getType() == EntityType.DROPPED_ITEM) {
|
if (entity.getType() == EntityType.DROPPED_ITEM) {
|
||||||
@ -128,6 +149,10 @@ public abstract class ChunkListener implements Listener {
|
|||||||
protected long physStart;
|
protected long physStart;
|
||||||
protected long physTick;
|
protected long physTick;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated see {@link com.fastasyncworldedit.bukkit.listener.ChunkListener} for an explanation of the deprecation
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "2.0.0")
|
||||||
public final void reset() {
|
public final void reset() {
|
||||||
physSkip = 0;
|
physSkip = 0;
|
||||||
physStart = System.currentTimeMillis();
|
physStart = System.currentTimeMillis();
|
||||||
@ -241,13 +266,13 @@ public abstract class ChunkListener implements Listener {
|
|||||||
if ((++physSkip & 1023) != 0) {
|
if ((++physSkip & 1023) != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
FaweTimer timer = Fawe.get().getTimer();
|
FaweTimer timer = Fawe.instance().getTimer();
|
||||||
if (timer.getTick() != physTick) {
|
if (timer.getTick() != physTick) {
|
||||||
physTick = timer.getTick();
|
physTick = timer.getTick();
|
||||||
physStart = System.currentTimeMillis();
|
physStart = System.currentTimeMillis();
|
||||||
return;
|
return;
|
||||||
} else if (System.currentTimeMillis() - physStart
|
} else if (System.currentTimeMillis() - physStart
|
||||||
< Settings.IMP.TICK_LIMITER.PHYSICS_MS) {
|
< Settings.settings().TICK_LIMITER.PHYSICS_MS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -324,15 +349,15 @@ public abstract class ChunkListener implements Listener {
|
|||||||
int cx = x >> 4;
|
int cx = x >> 4;
|
||||||
int cz = z >> 4;
|
int cz = z >> 4;
|
||||||
int[] count = getCount(cx, cz);
|
int[] count = getCount(cx, cz);
|
||||||
if (count[1] >= Settings.IMP.TICK_LIMITER.FALLING) {
|
if (count[1] >= Settings.settings().TICK_LIMITER.FALLING) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (event.getEntityType() == EntityType.FALLING_BLOCK) {
|
if (event.getEntityType() == EntityType.FALLING_BLOCK) {
|
||||||
if (++count[1] >= Settings.IMP.TICK_LIMITER.FALLING) {
|
if (++count[1] >= Settings.settings().TICK_LIMITER.FALLING) {
|
||||||
|
|
||||||
// Only cancel falling blocks when it's lagging
|
// Only cancel falling blocks when it's lagging
|
||||||
if (Fawe.get().getTimer().getTPS() < 18) {
|
if (Fawe.instance().getTimer().getTPS() < 18) {
|
||||||
cancelNearby(cx, cz);
|
cancelNearby(cx, cz);
|
||||||
if (rateLimit <= 0) {
|
if (rateLimit <= 0) {
|
||||||
rateLimit = 20;
|
rateLimit = 20;
|
||||||
@ -351,7 +376,7 @@ public abstract class ChunkListener implements Listener {
|
|||||||
*/
|
*/
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
public void onChunkLoad(ChunkLoadEvent event) {
|
public void onChunkLoad(ChunkLoadEvent event) {
|
||||||
if (!Settings.IMP.TICK_LIMITER.FIREWORKS_LOAD_CHUNKS) {
|
if (!Settings.settings().TICK_LIMITER.FIREWORKS_LOAD_CHUNKS) {
|
||||||
Chunk chunk = event.getChunk();
|
Chunk chunk = event.getChunk();
|
||||||
Entity[] entities = chunk.getEntities();
|
Entity[] entities = chunk.getEntities();
|
||||||
World world = chunk.getWorld();
|
World world = chunk.getWorld();
|
||||||
@ -377,8 +402,8 @@ public abstract class ChunkListener implements Listener {
|
|||||||
if (Math.abs(velocity.getX()) > vertical
|
if (Math.abs(velocity.getX()) > vertical
|
||||||
|| Math.abs(velocity.getZ()) > vertical) {
|
|| Math.abs(velocity.getZ()) > vertical) {
|
||||||
LOGGER.warn(
|
LOGGER.warn(
|
||||||
"[FAWE `tick-limiter`] Detected and cancelled rogue FireWork at "
|
"[FAWE `tick-limiter`] Detected and cancelled rogue FireWork at {}",
|
||||||
+ ent.getLocation());
|
ent.getLocation());
|
||||||
ent.remove();
|
ent.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -398,17 +423,17 @@ public abstract class ChunkListener implements Listener {
|
|||||||
int cx = loc.getBlockX() >> 4;
|
int cx = loc.getBlockX() >> 4;
|
||||||
int cz = loc.getBlockZ() >> 4;
|
int cz = loc.getBlockZ() >> 4;
|
||||||
int[] count = getCount(cx, cz);
|
int[] count = getCount(cx, cz);
|
||||||
if (count[2] >= Settings.IMP.TICK_LIMITER.ITEMS) {
|
if (count[2] >= Settings.settings().TICK_LIMITER.ITEMS) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (++count[2] >= Settings.IMP.TICK_LIMITER.ITEMS) {
|
if (++count[2] >= Settings.settings().TICK_LIMITER.ITEMS) {
|
||||||
cleanup(loc.getChunk());
|
cleanup(loc.getChunk());
|
||||||
cancelNearby(cx, cz);
|
cancelNearby(cx, cz);
|
||||||
if (rateLimit <= 0) {
|
if (rateLimit <= 0) {
|
||||||
rateLimit = 20;
|
rateLimit = 20;
|
||||||
LOGGER.warn(
|
LOGGER.warn(
|
||||||
"[FAWE `tick-limiter`] Detected and cancelled item lag source at " + loc);
|
"[FAWE `tick-limiter`] Detected and cancelled item lag source at {}", loc);
|
||||||
}
|
}
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,20 @@ import org.bukkit.event.EventHandler;
|
|||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated FAWE is not necessarily the tool you want to use to limit certain tick actions, e.g. fireworks or elytra flying.
|
||||||
|
* The code is untouched since the 1.12 era and there is no guarantee that it will work or will be maintained in the future.
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "2.0.0")
|
||||||
public class ChunkListener9 extends ChunkListener {
|
public class ChunkListener9 extends ChunkListener {
|
||||||
|
|
||||||
private Exception exception;
|
private Exception exception;
|
||||||
private StackTraceElement[] elements;
|
private StackTraceElement[] elements;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated see {@link com.fastasyncworldedit.bukkit.listener.ChunkListener9} for an explanation of the deprecation
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "2.0.0")
|
||||||
public ChunkListener9() {
|
public ChunkListener9() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@ -37,13 +46,13 @@ public class ChunkListener9 extends ChunkListener {
|
|||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (System.currentTimeMillis() - physStart > Settings.IMP.TICK_LIMITER.PHYSICS_MS) {
|
if (System.currentTimeMillis() - physStart > Settings.settings().TICK_LIMITER.PHYSICS_MS) {
|
||||||
physCancelPair = pair;
|
physCancelPair = pair;
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FaweTimer timer = Fawe.get().getTimer();
|
FaweTimer timer = Fawe.instance().getTimer();
|
||||||
if (timer.getTick() != physTick) {
|
if (timer.getTick() != physTick) {
|
||||||
physTick = timer.getTick();
|
physTick = timer.getTick();
|
||||||
physStart = System.currentTimeMillis();
|
physStart = System.currentTimeMillis();
|
||||||
@ -52,7 +61,7 @@ public class ChunkListener9 extends ChunkListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((++physSkip & 1023) == 0) {
|
if ((++physSkip & 1023) == 0) {
|
||||||
if (System.currentTimeMillis() - physStart > Settings.IMP.TICK_LIMITER.PHYSICS_MS) {
|
if (System.currentTimeMillis() - physStart > Settings.settings().TICK_LIMITER.PHYSICS_MS) {
|
||||||
Block block = event.getBlock();
|
Block block = event.getBlock();
|
||||||
int cx = block.getX() >> 4;
|
int cx = block.getX() >> 4;
|
||||||
int cz = block.getZ() >> 4;
|
int cz = block.getZ() >> 4;
|
||||||
|
@ -28,7 +28,7 @@ public class RenderListener implements Listener {
|
|||||||
|
|
||||||
public RenderListener(Plugin plugin) {
|
public RenderListener(Plugin plugin) {
|
||||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||||
TaskManager.IMP.repeat(new Runnable() {
|
TaskManager.taskManager().repeat(new Runnable() {
|
||||||
private long last = 0;
|
private long last = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -38,7 +38,7 @@ public class RenderListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
int tps32 = (int) (Math.round(Fawe.get().getTimer().getTPS()) * 32);
|
int tps32 = (int) (Math.round(Fawe.instance().getTimer().getTPS()) * 32);
|
||||||
long diff = now - last;
|
long diff = now - last;
|
||||||
last = now;
|
last = now;
|
||||||
if (diff > 75) {
|
if (diff > 75) {
|
||||||
@ -56,7 +56,7 @@ public class RenderListener implements Listener {
|
|||||||
if (entrySet == null || !entrySet.hasNext()) {
|
if (entrySet == null || !entrySet.hasNext()) {
|
||||||
entrySet = views.entrySet().iterator();
|
entrySet = views.entrySet().iterator();
|
||||||
}
|
}
|
||||||
int nowTick = (int) (Fawe.get().getTimer().getTick());
|
int nowTick = (int) (Fawe.instance().getTimer().getTick());
|
||||||
while (entrySet.hasNext()) {
|
while (entrySet.hasNext()) {
|
||||||
Map.Entry<UUID, int[]> entry = entrySet.next();
|
Map.Entry<UUID, int[]> entry = entrySet.next();
|
||||||
Player player = Bukkit.getPlayer(entry.getKey());
|
Player player = Bukkit.getPlayer(entry.getKey());
|
||||||
@ -81,17 +81,17 @@ public class RenderListener implements Listener {
|
|||||||
|
|
||||||
private void setViewDistance(Player player, int value) {
|
private void setViewDistance(Player player, int value) {
|
||||||
UUID uuid = player.getUniqueId();
|
UUID uuid = player.getUniqueId();
|
||||||
if (value == Settings.IMP.EXPERIMENTAL.DYNAMIC_CHUNK_RENDERING) {
|
if (value == Settings.settings().EXPERIMENTAL.DYNAMIC_CHUNK_RENDERING) {
|
||||||
views.remove(uuid);
|
views.remove(uuid);
|
||||||
} else {
|
} else {
|
||||||
int[] val = views.get(uuid);
|
int[] val = views.get(uuid);
|
||||||
if (val == null) {
|
if (val == null) {
|
||||||
val = new int[]{value, (int) Fawe.get().getTimer().getTick()};
|
val = new int[]{value, (int) Fawe.instance().getTimer().getTick()};
|
||||||
UUID uid = player.getUniqueId();
|
UUID uid = player.getUniqueId();
|
||||||
views.put(uid, val);
|
views.put(uid, val);
|
||||||
} else {
|
} else {
|
||||||
if (value <= val[0]) {
|
if (value <= val[0]) {
|
||||||
val[1] = (int) Fawe.get().getTimer().getTick();
|
val[1] = (int) Fawe.instance().getTimer().getTick();
|
||||||
}
|
}
|
||||||
if (val[0] == value) {
|
if (val[0] == value) {
|
||||||
return;
|
return;
|
||||||
@ -105,7 +105,7 @@ public class RenderListener implements Listener {
|
|||||||
|
|
||||||
private int getViewDistance(Player player) {
|
private int getViewDistance(Player player) {
|
||||||
int[] value = views.get(player.getUniqueId());
|
int[] value = views.get(player.getUniqueId());
|
||||||
return value == null ? Settings.IMP.EXPERIMENTAL.DYNAMIC_CHUNK_RENDERING : value[0];
|
return value == null ? Settings.settings().EXPERIMENTAL.DYNAMIC_CHUNK_RENDERING : value[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
@ -32,7 +32,7 @@ public class GriefDefenderFeature extends BukkitMaskManager implements Listener
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FaweMask getMask(final com.sk89q.worldedit.entity.Player wePlayer, MaskType type) {
|
public FaweMask getMask(final com.sk89q.worldedit.entity.Player wePlayer, MaskType type, boolean isWhitelist) {
|
||||||
final Player player = BukkitAdapter.adapt(wePlayer);
|
final Player player = BukkitAdapter.adapt(wePlayer);
|
||||||
final Location loc = player.getLocation();
|
final Location loc = player.getLocation();
|
||||||
final Vector3i vector = Vector3i.from(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
final Vector3i vector = Vector3i.from(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package com.fastasyncworldedit.bukkit.regions;
|
package com.fastasyncworldedit.bukkit.regions;
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.regions.FaweMask;
|
import com.fastasyncworldedit.core.regions.FaweMask;
|
||||||
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
|
import com.sk89q.worldedit.extension.platform.Capability;
|
||||||
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.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
@ -30,7 +32,7 @@ public class GriefPreventionFeature extends BukkitMaskManager implements Listene
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FaweMask getMask(final com.sk89q.worldedit.entity.Player wePlayer, MaskType type) {
|
public FaweMask getMask(final com.sk89q.worldedit.entity.Player wePlayer, MaskType type, boolean isWhitelist) {
|
||||||
final Player player = BukkitAdapter.adapt(wePlayer);
|
final Player player = BukkitAdapter.adapt(wePlayer);
|
||||||
final Claim claim = GriefPrevention.instance.dataStore.getClaimAt(player.getLocation(), true, null);
|
final Claim claim = GriefPrevention.instance.dataStore.getClaimAt(player.getLocation(), true, null);
|
||||||
if (claim != null) {
|
if (claim != null) {
|
||||||
@ -38,12 +40,12 @@ public class GriefPreventionFeature extends BukkitMaskManager implements Listene
|
|||||||
claim.getGreaterBoundaryCorner().getBlockX();
|
claim.getGreaterBoundaryCorner().getBlockX();
|
||||||
final BlockVector3 pos1 = BlockVector3.at(
|
final BlockVector3 pos1 = BlockVector3.at(
|
||||||
claim.getLesserBoundaryCorner().getBlockX(),
|
claim.getLesserBoundaryCorner().getBlockX(),
|
||||||
0,
|
player.getWorld().getMinHeight(),
|
||||||
claim.getLesserBoundaryCorner().getBlockZ()
|
claim.getLesserBoundaryCorner().getBlockZ()
|
||||||
);
|
);
|
||||||
final BlockVector3 pos2 = BlockVector3.at(
|
final BlockVector3 pos2 = BlockVector3.at(
|
||||||
claim.getGreaterBoundaryCorner().getBlockX(),
|
claim.getGreaterBoundaryCorner().getBlockX(),
|
||||||
256,
|
player.getWorld().getMaxHeight(),
|
||||||
claim.getGreaterBoundaryCorner().getBlockZ()
|
claim.getGreaterBoundaryCorner().getBlockZ()
|
||||||
);
|
);
|
||||||
return new FaweMask(new CuboidRegion(pos1, pos2)) {
|
return new FaweMask(new CuboidRegion(pos1, pos2)) {
|
||||||
|
@ -33,13 +33,13 @@ public class ResidenceFeature extends BukkitMaskManager implements Listener {
|
|||||||
return residence != null &&
|
return residence != null &&
|
||||||
(residence.getOwner().equals(player.getName()) ||
|
(residence.getOwner().equals(player.getName()) ||
|
||||||
residence.getOwner().equals(player.getUniqueId().toString()) ||
|
residence.getOwner().equals(player.getUniqueId().toString()) ||
|
||||||
type == MaskType.MEMBER && TaskManager.IMP.sync(() -> residence
|
type == MaskType.MEMBER && TaskManager.taskManager().sync(() -> residence
|
||||||
.getPermissions()
|
.getPermissions()
|
||||||
.playerHas(player, "build", false)));
|
.playerHas(player, "build", false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FaweMask getMask(final com.sk89q.worldedit.entity.Player wePlayer, final MaskType type) {
|
public FaweMask getMask(final com.sk89q.worldedit.entity.Player wePlayer, final MaskType type, boolean isWhitelist) {
|
||||||
final Player player = BukkitAdapter.adapt(wePlayer);
|
final Player player = BukkitAdapter.adapt(wePlayer);
|
||||||
final Location location = player.getLocation();
|
final Location location = player.getLocation();
|
||||||
ClaimedResidence residence = Residence.getInstance().getResidenceManager().getByLoc(location);
|
ClaimedResidence residence = Residence.getInstance().getResidenceManager().getByLoc(location);
|
||||||
|
@ -66,7 +66,7 @@ public class TownyFeature extends BukkitMaskManager implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FaweMask getMask(final com.sk89q.worldedit.entity.Player wePlayer, MaskType type) {
|
public FaweMask getMask(final com.sk89q.worldedit.entity.Player wePlayer, MaskType type, boolean isWhitelist) {
|
||||||
final Player player = BukkitAdapter.adapt(wePlayer);
|
final Player player = BukkitAdapter.adapt(wePlayer);
|
||||||
final Location location = player.getLocation();
|
final Location location = player.getLocation();
|
||||||
try {
|
try {
|
||||||
|
@ -53,7 +53,7 @@ public class FaweDelegateRegionManager {
|
|||||||
int maxY,
|
int maxY,
|
||||||
Runnable whenDone
|
Runnable whenDone
|
||||||
) {
|
) {
|
||||||
TaskManager.IMP.async(() -> {
|
TaskManager.taskManager().async(() -> {
|
||||||
synchronized (FaweDelegateRegionManager.class) {
|
synchronized (FaweDelegateRegionManager.class) {
|
||||||
World world = BukkitAdapter.adapt(getWorld(area.getWorldName()));
|
World world = BukkitAdapter.adapt(getWorld(area.getWorldName()));
|
||||||
EditSession session = WorldEdit.getInstance().newEditSessionBuilder().world(world).checkMemory(false).
|
EditSession session = WorldEdit.getInstance().newEditSessionBuilder().world(world).checkMemory(false).
|
||||||
@ -67,14 +67,14 @@ public class FaweDelegateRegionManager {
|
|||||||
session.flushQueue();
|
session.flushQueue();
|
||||||
for (CuboidRegion region : regions) {
|
for (CuboidRegion region : regions) {
|
||||||
FaweAPI.fixLighting(world, region, null,
|
FaweAPI.fixLighting(world, region, null,
|
||||||
RelightMode.valueOf(com.fastasyncworldedit.core.configuration.Settings.IMP.LIGHTING.MODE)
|
RelightMode.valueOf(com.fastasyncworldedit.core.configuration.Settings.settings().LIGHTING.MODE)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (MaxChangedBlocksException e) {
|
} catch (MaxChangedBlocksException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
if (whenDone != null) {
|
if (whenDone != null) {
|
||||||
TaskManager.IMP.task(whenDone);
|
TaskManager.taskManager().task(whenDone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ public class FaweDelegateRegionManager {
|
|||||||
@Nullable Runnable whenDone,
|
@Nullable Runnable whenDone,
|
||||||
@Nonnull PlotManager manager
|
@Nonnull PlotManager manager
|
||||||
) {
|
) {
|
||||||
TaskManager.IMP.async(() -> {
|
TaskManager.taskManager().async(() -> {
|
||||||
synchronized (FaweDelegateRegionManager.class) {
|
synchronized (FaweDelegateRegionManager.class) {
|
||||||
final HybridPlotWorld hybridPlotWorld = ((HybridPlotManager) manager).getHybridPlotWorld();
|
final HybridPlotWorld hybridPlotWorld = ((HybridPlotManager) manager).getHybridPlotWorld();
|
||||||
World world = BukkitAdapter.adapt(getWorld(hybridPlotWorld.getWorldName()));
|
World world = BukkitAdapter.adapt(getWorld(hybridPlotWorld.getWorldName()));
|
||||||
@ -176,10 +176,10 @@ public class FaweDelegateRegionManager {
|
|||||||
world,
|
world,
|
||||||
new CuboidRegion(plot.getBottomAbs().getBlockVector3(), plot.getTopAbs().getBlockVector3()),
|
new CuboidRegion(plot.getBottomAbs().getBlockVector3(), plot.getTopAbs().getBlockVector3()),
|
||||||
null,
|
null,
|
||||||
RelightMode.valueOf(com.fastasyncworldedit.core.configuration.Settings.IMP.LIGHTING.MODE)
|
RelightMode.valueOf(com.fastasyncworldedit.core.configuration.Settings.settings().LIGHTING.MODE)
|
||||||
);
|
);
|
||||||
if (whenDone != null) {
|
if (whenDone != null) {
|
||||||
TaskManager.IMP.task(whenDone);
|
TaskManager.taskManager().task(whenDone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -192,7 +192,7 @@ public class FaweDelegateRegionManager {
|
|||||||
Location swapPos,
|
Location swapPos,
|
||||||
final Runnable whenDone
|
final Runnable whenDone
|
||||||
) {
|
) {
|
||||||
TaskManager.IMP.async(() -> {
|
TaskManager.taskManager().async(() -> {
|
||||||
synchronized (FaweDelegateRegionManager.class) {
|
synchronized (FaweDelegateRegionManager.class) {
|
||||||
//todo because of the following code this should proably be in the Bukkit module
|
//todo because of the following code this should proably be in the Bukkit module
|
||||||
World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorldName()));
|
World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorldName()));
|
||||||
@ -220,18 +220,22 @@ public class FaweDelegateRegionManager {
|
|||||||
Clipboard clipB = Clipboard.create(regionB, UUID.randomUUID());
|
Clipboard clipB = Clipboard.create(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);
|
||||||
|
copyB.setCopyingBiomes(true);
|
||||||
try {
|
try {
|
||||||
Operations.completeLegacy(copyA);
|
Operations.completeLegacy(copyA);
|
||||||
Operations.completeLegacy(copyB);
|
Operations.completeLegacy(copyB);
|
||||||
clipA.paste(sessionB, swapPos.getBlockVector3(), true);
|
clipA.flush();
|
||||||
clipB.paste(sessionA, pos1.getBlockVector3(), true);
|
clipB.flush();
|
||||||
sessionA.flushQueue();
|
clipA.paste(sessionB, swapPos.getBlockVector3(), true, true, true);
|
||||||
sessionB.flushQueue();
|
clipB.paste(sessionA, pos1.getBlockVector3(), true, true, true);
|
||||||
|
sessionA.close();
|
||||||
|
sessionB.close();
|
||||||
} catch (MaxChangedBlocksException e) {
|
} catch (MaxChangedBlocksException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
FaweAPI.fixLighting(pos1World, new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()), null,
|
FaweAPI.fixLighting(pos1World, new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()), null,
|
||||||
RelightMode.valueOf(com.fastasyncworldedit.core.configuration.Settings.IMP.LIGHTING.MODE)
|
RelightMode.valueOf(com.fastasyncworldedit.core.configuration.Settings.settings().LIGHTING.MODE)
|
||||||
);
|
);
|
||||||
FaweAPI.fixLighting(pos1World, new CuboidRegion(
|
FaweAPI.fixLighting(pos1World, new CuboidRegion(
|
||||||
swapPos.getBlockVector3(),
|
swapPos.getBlockVector3(),
|
||||||
@ -241,10 +245,10 @@ public class FaweDelegateRegionManager {
|
|||||||
swapPos.getZ() + pos2.getZ() - pos1.getZ()
|
swapPos.getZ() + pos2.getZ() - pos1.getZ()
|
||||||
)
|
)
|
||||||
), null,
|
), null,
|
||||||
RelightMode.valueOf(com.fastasyncworldedit.core.configuration.Settings.IMP.LIGHTING.MODE)
|
RelightMode.valueOf(com.fastasyncworldedit.core.configuration.Settings.settings().LIGHTING.MODE)
|
||||||
);
|
);
|
||||||
if (whenDone != null) {
|
if (whenDone != null) {
|
||||||
TaskManager.IMP.task(whenDone);
|
TaskManager.taskManager().task(whenDone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -253,7 +257,7 @@ public class FaweDelegateRegionManager {
|
|||||||
public void setBiome(CuboidRegion region, int extendBiome, BiomeType biome, String world, Runnable whenDone) {
|
public void setBiome(CuboidRegion region, int extendBiome, BiomeType biome, String world, Runnable whenDone) {
|
||||||
region.expand(BlockVector3.at(extendBiome, 0, extendBiome));
|
region.expand(BlockVector3.at(extendBiome, 0, extendBiome));
|
||||||
region.expand(BlockVector3.at(-extendBiome, 0, -extendBiome));
|
region.expand(BlockVector3.at(-extendBiome, 0, -extendBiome));
|
||||||
TaskManager.IMP.async(() -> {
|
TaskManager.taskManager().async(() -> {
|
||||||
synchronized (FaweDelegateRegionManager.class) {
|
synchronized (FaweDelegateRegionManager.class) {
|
||||||
EditSession editSession = WorldEdit
|
EditSession editSession = WorldEdit
|
||||||
.getInstance()
|
.getInstance()
|
||||||
@ -273,7 +277,7 @@ public class FaweDelegateRegionManager {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
if (whenDone != null) {
|
if (whenDone != null) {
|
||||||
TaskManager.IMP.task(whenDone);
|
TaskManager.taskManager().task(whenDone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -285,7 +289,7 @@ public class FaweDelegateRegionManager {
|
|||||||
final @NonNull Location pos3,
|
final @NonNull Location pos3,
|
||||||
final @NonNull Runnable whenDone
|
final @NonNull Runnable whenDone
|
||||||
) {
|
) {
|
||||||
TaskManager.IMP.async(() -> {
|
TaskManager.taskManager().async(() -> {
|
||||||
synchronized (FaweDelegateRegionManager.class) {
|
synchronized (FaweDelegateRegionManager.class) {
|
||||||
World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorldName()));
|
World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorldName()));
|
||||||
World pos3World = BukkitAdapter.adapt(getWorld(pos3.getWorldName()));
|
World pos3World = BukkitAdapter.adapt(getWorld(pos3.getWorldName()));
|
||||||
@ -319,21 +323,21 @@ public class FaweDelegateRegionManager {
|
|||||||
pos3.getBlockVector3(),
|
pos3.getBlockVector3(),
|
||||||
pos3.getBlockVector3().add(pos2.getBlockVector3().subtract(pos1.getBlockVector3()))
|
pos3.getBlockVector3().add(pos2.getBlockVector3().subtract(pos1.getBlockVector3()))
|
||||||
),
|
),
|
||||||
null, RelightMode.valueOf(com.fastasyncworldedit.core.configuration.Settings.IMP.LIGHTING.MODE)
|
null, RelightMode.valueOf(com.fastasyncworldedit.core.configuration.Settings.settings().LIGHTING.MODE)
|
||||||
);
|
);
|
||||||
} catch (MaxChangedBlocksException e) {
|
} catch (MaxChangedBlocksException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (whenDone != null) {
|
if (whenDone != null) {
|
||||||
TaskManager.IMP.task(whenDone);
|
TaskManager.taskManager().task(whenDone);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean regenerateRegion(final Location pos1, final Location pos2, boolean ignore, final Runnable whenDone) {
|
public boolean regenerateRegion(final Location pos1, final Location pos2, boolean ignore, final Runnable whenDone) {
|
||||||
TaskManager.IMP.async(() -> {
|
TaskManager.taskManager().async(() -> {
|
||||||
synchronized (FaweDelegateRegionManager.class) {
|
synchronized (FaweDelegateRegionManager.class) {
|
||||||
World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorldName()));
|
World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorldName()));
|
||||||
try (EditSession editSession = WorldEdit.getInstance().newEditSessionBuilder().world(pos1World)
|
try (EditSession editSession = WorldEdit.getInstance().newEditSessionBuilder().world(pos1World)
|
||||||
@ -350,7 +354,7 @@ public class FaweDelegateRegionManager {
|
|||||||
editSession.flushQueue();
|
editSession.flushQueue();
|
||||||
}
|
}
|
||||||
if (whenDone != null) {
|
if (whenDone != null) {
|
||||||
TaskManager.IMP.task(whenDone);
|
TaskManager.taskManager().task(whenDone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -132,7 +132,7 @@ public class FaweDelegateSchematicHandler {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (Fawe.isMainThread()) {
|
if (Fawe.isMainThread()) {
|
||||||
com.fastasyncworldedit.core.util.TaskManager.IMP.async(r);
|
com.fastasyncworldedit.core.util.TaskManager.taskManager().async(r);
|
||||||
} else {
|
} else {
|
||||||
r.run();
|
r.run();
|
||||||
}
|
}
|
||||||
@ -186,7 +186,7 @@ public class FaweDelegateSchematicHandler {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final CompoundTag weTag = (CompoundTag) FaweCache.IMP.asTag(tag);
|
final CompoundTag weTag = (CompoundTag) FaweCache.INSTANCE.asTag(tag);
|
||||||
SchematicHandler.upload(uuid, file, "schem", new RunnableVal<>() {
|
SchematicHandler.upload(uuid, file, "schem", new RunnableVal<>() {
|
||||||
@Override
|
@Override
|
||||||
public void run(OutputStream output) {
|
public void run(OutputStream output) {
|
||||||
@ -235,10 +235,8 @@ public class FaweDelegateSchematicHandler {
|
|||||||
Clipboard clip = schematicReader.read();
|
Clipboard clip = schematicReader.read();
|
||||||
return new Schematic(clip);
|
return new Schematic(clip);
|
||||||
} catch (IOException e3) {
|
} catch (IOException e3) {
|
||||||
|
LOGGER.warn("{} | {} : {}", is, is.getClass().getCanonicalName(), e.getMessage());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
LOGGER.warn(
|
|
||||||
is + " | " + is.getClass().getCanonicalName() + " is not in GZIP format : " + e
|
|
||||||
.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,8 +35,8 @@ public class FaweQueueCoordinator extends QueueCoordinator {
|
|||||||
public FaweQueueCoordinator(World world) {
|
public FaweQueueCoordinator(World world) {
|
||||||
super(world);
|
super(world);
|
||||||
this.world = world;
|
this.world = world;
|
||||||
instance = Fawe.get().getQueueHandler().getQueue(world);
|
instance = Fawe.instance().getQueueHandler().getQueue(world);
|
||||||
Fawe.get().getQueueHandler().unCache();
|
Fawe.instance().getQueueHandler().unCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -194,7 +194,7 @@ public class FaweQueueCoordinator extends QueueCoordinator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setTile(int x, int y, int z, CompoundTag tag) {
|
public boolean setTile(int x, int y, int z, CompoundTag tag) {
|
||||||
instance.setTile(x, y, z, (com.sk89q.jnbt.CompoundTag) FaweCache.IMP.asTag(tag));
|
instance.setTile(x, y, z, (com.sk89q.jnbt.CompoundTag) FaweCache.INSTANCE.asTag(tag));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ public class FaweTrim extends SubCommand {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ran = true;
|
ran = true;
|
||||||
TaskManager.IMP.async(() -> {
|
TaskManager.taskManager().async(() -> {
|
||||||
try {
|
try {
|
||||||
// TODO NOT IMPLEMENTED
|
// TODO NOT IMPLEMENTED
|
||||||
//PlotTrim trim = new PlotTrim(plotPlayer, plotPlayer.getPlotAreaAbs(), strings[0], Boolean.parseBoolean(strings[1]));
|
//PlotTrim trim = new PlotTrim(plotPlayer, plotPlayer.getPlotAreaAbs(), strings[0], Boolean.parseBoolean(strings[1]));
|
||||||
|
@ -89,7 +89,7 @@ public class PlotSetBiome extends Command {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
plot.addRunning();
|
plot.addRunning();
|
||||||
TaskManager.IMP.async(() -> {
|
TaskManager.taskManager().async(() -> {
|
||||||
EditSession session =
|
EditSession session =
|
||||||
WorldEdit
|
WorldEdit
|
||||||
.getInstance()
|
.getInstance()
|
||||||
|
@ -4,9 +4,6 @@ import com.fastasyncworldedit.core.FaweAPI;
|
|||||||
import com.fastasyncworldedit.core.configuration.Caption;
|
import com.fastasyncworldedit.core.configuration.Caption;
|
||||||
import com.fastasyncworldedit.core.regions.FaweMask;
|
import com.fastasyncworldedit.core.regions.FaweMask;
|
||||||
import com.fastasyncworldedit.core.regions.FaweMaskManager;
|
import com.fastasyncworldedit.core.regions.FaweMaskManager;
|
||||||
import com.fastasyncworldedit.core.regions.filter.RegionFilter;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
|
|
||||||
import com.plotsquared.core.PlotSquared;
|
|
||||||
import com.plotsquared.core.configuration.Settings;
|
import com.plotsquared.core.configuration.Settings;
|
||||||
import com.plotsquared.core.database.DBFunc;
|
import com.plotsquared.core.database.DBFunc;
|
||||||
import com.plotsquared.core.player.PlotPlayer;
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
@ -62,6 +59,15 @@ public class PlotSquaredFeature extends FaweMaskManager {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the player is allowed to use FAWE on a PlotSquared plot.
|
||||||
|
*
|
||||||
|
* @param player the {@link Player}
|
||||||
|
* @param plot the {@link Plot}
|
||||||
|
* @param type the {@link MaskType}
|
||||||
|
* @return {@code true} if the player is the plot owner, trusted, has the permission fawe.plotsquared.member
|
||||||
|
* or fawe.plotsquared.admin and the NoWorldeditFlag is not set; otherwise {@code false}
|
||||||
|
*/
|
||||||
public boolean isAllowed(Player player, Plot plot, MaskType type) {
|
public boolean isAllowed(Player player, Plot plot, MaskType type) {
|
||||||
if (plot == null) {
|
if (plot == null) {
|
||||||
return false;
|
return false;
|
||||||
@ -121,7 +127,7 @@ public class PlotSquaredFeature extends FaweMaskManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FaweMask getMask(Player player, MaskType type) {
|
public FaweMask getMask(Player player, MaskType type, boolean isWhitelist) {
|
||||||
final PlotPlayer<org.bukkit.entity.Player> pp = PlotPlayer.from(BukkitAdapter.adapt(player));
|
final PlotPlayer<org.bukkit.entity.Player> pp = PlotPlayer.from(BukkitAdapter.adapt(player));
|
||||||
if (pp == null) {
|
if (pp == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -46,9 +46,9 @@ public class ReplaceAll extends Command {
|
|||||||
plot.addRunning();
|
plot.addRunning();
|
||||||
FawePlayer<Object> fp = FawePlayer.wrap(player.getName());
|
FawePlayer<Object> fp = FawePlayer.wrap(player.getName());
|
||||||
Captions.TASK_START.send(player);
|
Captions.TASK_START.send(player);
|
||||||
TaskManager.IMP.async(() -> fp.runAction(() -> {
|
TaskManager.taskManager().async(() -> fp.runAction(() -> {
|
||||||
String worldName = plot.getWorldName();
|
String worldName = plot.getWorldName();
|
||||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
TaskManager.taskManager().sync(new RunnableVal<Object>() {
|
||||||
@Override
|
@Override
|
||||||
public void run(Object value) {
|
public void run(Object value) {
|
||||||
SetupUtils.manager.unload(worldName, true);
|
SetupUtils.manager.unload(worldName, true);
|
||||||
@ -58,7 +58,7 @@ public class ReplaceAll extends Command {
|
|||||||
String cmd = "/replaceallpattern " + worldName + " " + StringMan.join(args, " ");
|
String cmd = "/replaceallpattern " + worldName + " " + StringMan.join(args, " ");
|
||||||
CommandEvent event = new CommandEvent(actor, cmd);
|
CommandEvent event = new CommandEvent(actor, cmd);
|
||||||
PlatformCommandManager.getInstance().handleCommandOnCurrentThread(event);
|
PlatformCommandManager.getInstance().handleCommandOnCurrentThread(event);
|
||||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
TaskManager.taskManager().sync(new RunnableVal<Object>() {
|
||||||
@Override
|
@Override
|
||||||
public void run(Object value) {
|
public void run(Object value) {
|
||||||
plot.teleportPlayer(player);
|
plot.teleportPlayer(player);
|
||||||
|
@ -1,172 +0,0 @@
|
|||||||
package com.fastasyncworldedit.bukkit.regions.plotsquaredv4;
|
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.configuration.Settings;
|
|
||||||
import com.fastasyncworldedit.core.util.TaskManager;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.object.Location;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.util.ChunkManager;
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
|
||||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
|
||||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
|
||||||
import com.sk89q.worldedit.function.operation.Operations;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
|
||||||
import com.sk89q.worldedit.world.World;
|
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
import static org.bukkit.Bukkit.getWorld;
|
|
||||||
|
|
||||||
public class FaweChunkManager extends ChunkManager {
|
|
||||||
|
|
||||||
private final ChunkManager parent;
|
|
||||||
|
|
||||||
public FaweChunkManager(ChunkManager parent) {
|
|
||||||
this.parent = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int[] countEntities(Plot plot) {
|
|
||||||
return parent.countEntities(plot);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletableFuture loadChunk(String world, BlockVector2 loc, boolean force) {
|
|
||||||
return parent.loadChunk(world, loc, force);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unloadChunk(String world, BlockVector2 loc, boolean save) {
|
|
||||||
parent.unloadChunk(world, loc, save);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearAllEntities(Location pos1, Location pos2) {
|
|
||||||
parent.clearAllEntities(pos1, pos2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void swap(
|
|
||||||
final Location pos1,
|
|
||||||
final Location pos2,
|
|
||||||
final Location pos3,
|
|
||||||
final Location pos4,
|
|
||||||
final Runnable whenDone
|
|
||||||
) {
|
|
||||||
if (!Settings.IMP.PLOTSQUARED_INTEGRATION.COPY_AND_SWAP) {
|
|
||||||
parent.swap(pos1, pos2, pos3, pos4, whenDone);
|
|
||||||
}
|
|
||||||
TaskManager.IMP.async(() -> {
|
|
||||||
synchronized (FaweChunkManager.class) {
|
|
||||||
//todo because of the following code this should proably be in the Bukkit module
|
|
||||||
World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorld()));
|
|
||||||
World pos3World = BukkitAdapter.adapt(getWorld(pos3.getWorld()));
|
|
||||||
EditSession sessionA = WorldEdit.getInstance().newEditSessionBuilder().world(pos1World)
|
|
||||||
.checkMemory(false)
|
|
||||||
.fastMode(true)
|
|
||||||
.limitUnlimited()
|
|
||||||
.changeSetNull()
|
|
||||||
.build();
|
|
||||||
EditSession sessionB = WorldEdit.getInstance().newEditSessionBuilder().world(pos3World)
|
|
||||||
.checkMemory(false)
|
|
||||||
.fastMode(true)
|
|
||||||
.limitUnlimited()
|
|
||||||
.changeSetNull()
|
|
||||||
.build();
|
|
||||||
CuboidRegion regionA = new CuboidRegion(
|
|
||||||
BlockVector3.at(pos1.getX(), pos1.getY(), pos1.getZ()),
|
|
||||||
BlockVector3.at(pos2.getX(), pos2.getY(), pos2.getZ())
|
|
||||||
);
|
|
||||||
CuboidRegion regionB = new CuboidRegion(
|
|
||||||
BlockVector3.at(pos3.getX(), pos3.getY(), pos3.getZ()),
|
|
||||||
BlockVector3.at(pos4.getX(), pos4.getY(), pos4.getZ())
|
|
||||||
);
|
|
||||||
ForwardExtentCopy copyA = new ForwardExtentCopy(sessionA, regionA, sessionB, regionB.getMinimumPoint());
|
|
||||||
ForwardExtentCopy copyB = new ForwardExtentCopy(sessionB, regionB, sessionA, regionA.getMinimumPoint());
|
|
||||||
try {
|
|
||||||
Operations.completeLegacy(copyA);
|
|
||||||
Operations.completeLegacy(copyB);
|
|
||||||
sessionA.flushQueue();
|
|
||||||
sessionB.flushQueue();
|
|
||||||
} catch (MaxChangedBlocksException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
TaskManager.IMP.task(whenDone);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean copyRegion(final Location pos1, final Location pos2, final Location pos3, final Runnable whenDone) {
|
|
||||||
if (!Settings.IMP.PLOTSQUARED_INTEGRATION.COPY_AND_SWAP) {
|
|
||||||
return parent.copyRegion(pos1, pos2, pos3, whenDone);
|
|
||||||
}
|
|
||||||
TaskManager.IMP.async(() -> {
|
|
||||||
synchronized (FaweChunkManager.class) {
|
|
||||||
World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorld()));
|
|
||||||
World pos3World = BukkitAdapter.adapt(getWorld(pos3.getWorld()));
|
|
||||||
EditSession from = WorldEdit.getInstance().newEditSessionBuilder().world(pos1World)
|
|
||||||
.checkMemory(false)
|
|
||||||
.fastMode(true)
|
|
||||||
.limitUnlimited()
|
|
||||||
.changeSetNull()
|
|
||||||
.build();
|
|
||||||
EditSession to = WorldEdit.getInstance().newEditSessionBuilder().world(pos3World)
|
|
||||||
.checkMemory(false)
|
|
||||||
.fastMode(true)
|
|
||||||
.limitUnlimited()
|
|
||||||
.changeSetNull()
|
|
||||||
.build();
|
|
||||||
CuboidRegion region = new CuboidRegion(
|
|
||||||
BlockVector3.at(pos1.getX(), pos1.getY(), pos1.getZ()),
|
|
||||||
BlockVector3.at(pos2.getX(), pos2.getY(), pos2.getZ())
|
|
||||||
);
|
|
||||||
ForwardExtentCopy copy = new ForwardExtentCopy(
|
|
||||||
from,
|
|
||||||
region,
|
|
||||||
to,
|
|
||||||
BlockVector3.at(pos3.getX(), pos3.getY(), pos3.getZ())
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
Operations.completeLegacy(copy);
|
|
||||||
to.flushQueue();
|
|
||||||
} catch (MaxChangedBlocksException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TaskManager.IMP.task(whenDone);
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean regenerateRegion(final Location pos1, final Location pos2, boolean ignore, final Runnable whenDone) {
|
|
||||||
TaskManager.IMP.async(() -> {
|
|
||||||
synchronized (FaweChunkManager.class) {
|
|
||||||
World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorld()));
|
|
||||||
try (EditSession editSession = WorldEdit
|
|
||||||
.getInstance()
|
|
||||||
.newEditSessionBuilder()
|
|
||||||
.world(pos1World)
|
|
||||||
.checkMemory(false)
|
|
||||||
.fastMode(true)
|
|
||||||
.limitUnlimited()
|
|
||||||
.changeSetNull()
|
|
||||||
.build()) {
|
|
||||||
CuboidRegion region = new CuboidRegion(
|
|
||||||
BlockVector3.at(pos1.getX(), pos1.getY(), pos1.getZ()),
|
|
||||||
BlockVector3.at(pos2.getX(), pos2.getY(), pos2.getZ())
|
|
||||||
);
|
|
||||||
editSession.regenerate(region);
|
|
||||||
editSession.flushQueue();
|
|
||||||
}
|
|
||||||
TaskManager.IMP.task(whenDone);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,131 +0,0 @@
|
|||||||
package com.fastasyncworldedit.bukkit.regions.plotsquaredv4;
|
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.Fawe;
|
|
||||||
import com.fastasyncworldedit.core.FaweAPI;
|
|
||||||
import com.fastasyncworldedit.core.FaweCache;
|
|
||||||
import com.fastasyncworldedit.core.math.MutableBlockVector3;
|
|
||||||
import com.fastasyncworldedit.core.queue.IQueueChunk;
|
|
||||||
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue;
|
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
|
||||||
import com.sk89q.worldedit.world.World;
|
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
|
||||||
|
|
||||||
// TODO FIXME
|
|
||||||
public class FaweLocalBlockQueue extends LocalBlockQueue {
|
|
||||||
|
|
||||||
public final IQueueExtent<IQueueChunk> instance;
|
|
||||||
private final World world;
|
|
||||||
private final BlockVector3 mutable = new MutableBlockVector3();
|
|
||||||
|
|
||||||
public FaweLocalBlockQueue(String worldName) {
|
|
||||||
super(worldName);
|
|
||||||
this.world = FaweAPI.getWorld(worldName);
|
|
||||||
instance = Fawe.get().getQueueHandler().getQueue(world);
|
|
||||||
Fawe.get().getQueueHandler().unCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean next() {
|
|
||||||
if (!instance.isEmpty()) {
|
|
||||||
instance.flush();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void startSet(boolean parallel) {
|
|
||||||
Fawe.get().getQueueHandler().startSet(parallel);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void endSet(boolean parallel) {
|
|
||||||
Fawe.get().getQueueHandler().endSet(parallel);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return instance.isEmpty() ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void optimize() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setModified(long l) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getModified() {
|
|
||||||
return instance.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean setBlock(final int x, final int y, final int z, final BlockState id) {
|
|
||||||
return instance.setBlock(x, y, z, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean setBlock(int x, int y, int z, Pattern pattern) {
|
|
||||||
mutable.setComponents(x, y, z);
|
|
||||||
return pattern.apply(instance, mutable, mutable);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean setBlock(final int x, final int y, final int z, final BaseBlock id) {
|
|
||||||
return instance.setBlock(x, y, z, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getBlock(int x, int y, int z) {
|
|
||||||
return instance.getBlock(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean setBiome(int x, int z, BiomeType biomeType) {
|
|
||||||
return instance.setBiome(x, 0, z, biomeType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getWorld() {
|
|
||||||
return world.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void flush() {
|
|
||||||
instance.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean enqueue() {
|
|
||||||
boolean val = super.enqueue();
|
|
||||||
instance.enableQueue();
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refreshChunk(int x, int z) {
|
|
||||||
world.refreshChunk(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fixChunkLighting(int x, int z) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void regenChunk(int x, int z) {
|
|
||||||
instance.regenerateChunk(x, z, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean setTile(int x, int y, int z, CompoundTag tag) {
|
|
||||||
instance.setTile(x, y, z, (com.sk89q.jnbt.CompoundTag) FaweCache.IMP.asTag(tag));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,154 +0,0 @@
|
|||||||
package com.fastasyncworldedit.bukkit.regions.plotsquaredv4;
|
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.FaweAPI;
|
|
||||||
import com.fastasyncworldedit.core.FaweCache;
|
|
||||||
import com.fastasyncworldedit.core.extent.clipboard.ReadOnlyClipboard;
|
|
||||||
import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicWriter;
|
|
||||||
import com.fastasyncworldedit.core.jnbt.CompressedCompoundTag;
|
|
||||||
import com.fastasyncworldedit.core.jnbt.CompressedSchematicTag;
|
|
||||||
import com.fastasyncworldedit.core.util.IOUtil;
|
|
||||||
import com.fastasyncworldedit.core.util.TaskManager;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.object.Location;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue;
|
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
|
||||||
import com.sk89q.jnbt.NBTOutputStream;
|
|
||||||
import com.sk89q.jnbt.Tag;
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
|
||||||
import com.sk89q.worldedit.world.World;
|
|
||||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
|
||||||
import org.anarres.parallelgzip.ParallelGZIPOutputStream;
|
|
||||||
|
|
||||||
import java.io.BufferedOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import static org.bukkit.Bukkit.getWorld;
|
|
||||||
|
|
||||||
public class FaweSchematicHandler extends SchematicHandler {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean restoreTile(LocalBlockQueue queue, CompoundTag compoundTag, int x, int y, int z) {
|
|
||||||
if (queue instanceof FaweLocalBlockQueue) {
|
|
||||||
queue.setTile(x, y, z, compoundTag);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void getCompoundTag(final String world, final Set<CuboidRegion> regions, final RunnableVal<CompoundTag> whenDone) {
|
|
||||||
TaskManager.IMP.async(() -> {
|
|
||||||
Location[] corners = MainUtil.getCorners(world, regions);
|
|
||||||
Location pos1 = corners[0];
|
|
||||||
Location pos2 = corners[1];
|
|
||||||
World adaptedWorld = BukkitAdapter.adapt(getWorld(world));
|
|
||||||
final CuboidRegion region = new CuboidRegion(
|
|
||||||
BlockVector3.at(pos1.getX(), pos1.getY(), pos1.getZ()),
|
|
||||||
BlockVector3.at(pos2.getX(), pos2.getY(), pos2.getZ())
|
|
||||||
);
|
|
||||||
final EditSession editSession = WorldEdit.getInstance().newEditSessionBuilder().world(adaptedWorld)
|
|
||||||
.checkMemory(false)
|
|
||||||
.fastMode(true)
|
|
||||||
.limitUnlimited()
|
|
||||||
.changeSetNull()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
ReadOnlyClipboard clipboard = ReadOnlyClipboard.of(editSession, region, false, true);
|
|
||||||
|
|
||||||
Clipboard holder = new BlockArrayClipboard(region, clipboard);
|
|
||||||
|
|
||||||
CompressedSchematicTag tag = new CompressedSchematicTag(holder);
|
|
||||||
whenDone.run(tag);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean save(CompoundTag tag, String path) {
|
|
||||||
if (tag == null) {
|
|
||||||
PlotSquared.debug("&cCannot save empty tag");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
File tmp = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), path);
|
|
||||||
tmp.getParentFile().mkdirs();
|
|
||||||
if (tag instanceof CompressedCompoundTag) {
|
|
||||||
CompressedCompoundTag cTag = (CompressedCompoundTag) tag;
|
|
||||||
if (cTag instanceof CompressedSchematicTag) {
|
|
||||||
Clipboard clipboard = (Clipboard) cTag.getSource();
|
|
||||||
try (OutputStream stream = new FileOutputStream(tmp); NBTOutputStream output = new NBTOutputStream(new BufferedOutputStream(
|
|
||||||
new ParallelGZIPOutputStream(stream)))) {
|
|
||||||
new FastSchematicWriter(output).write(clipboard);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try (OutputStream stream = new FileOutputStream(tmp); BufferedOutputStream output = new BufferedOutputStream(
|
|
||||||
new ParallelGZIPOutputStream(stream))) {
|
|
||||||
LZ4BlockInputStream is = cTag.adapt(cTag.getSource());
|
|
||||||
IOUtil.copy(is, stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try (OutputStream stream = new FileOutputStream(tmp); NBTOutputStream output = new NBTOutputStream(new ParallelGZIPOutputStream(
|
|
||||||
stream))) {
|
|
||||||
Map<String, Tag> map = tag.getValue();
|
|
||||||
output.writeNamedTag("Schematic", map.getOrDefault("Schematic", tag));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void upload(final CompoundTag tag, final UUID uuid, final String file, final RunnableVal<URL> whenDone) {
|
|
||||||
if (tag == null) {
|
|
||||||
PlotSquared.debug("&cCannot save empty tag");
|
|
||||||
com.github.intellectualsites.plotsquared.plot.util.TaskManager.runTask(whenDone);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
CompoundTag weTag = (CompoundTag) FaweCache.IMP.asTag(tag);
|
|
||||||
if (weTag instanceof CompressedSchematicTag) {
|
|
||||||
Clipboard clipboard = ((CompressedSchematicTag) weTag).getSource();
|
|
||||||
URL url = FaweAPI.upload(clipboard, BuiltInClipboardFormat.SPONGE_SCHEMATIC);
|
|
||||||
whenDone.run(url);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
MainUtil.upload(uuid, file, "schem", new RunnableVal<OutputStream>() {
|
|
||||||
@Override
|
|
||||||
public void run(OutputStream output) {
|
|
||||||
try {
|
|
||||||
try (ParallelGZIPOutputStream gzip = new ParallelGZIPOutputStream(output)) {
|
|
||||||
try (NBTOutputStream nos = new NBTOutputStream(gzip)) {
|
|
||||||
Map<String, Tag> map = weTag.getValue();
|
|
||||||
nos.writeNamedTag("Schematic", map.getOrDefault("Schematic", weTag));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, whenDone);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
package com.fastasyncworldedit.bukkit.regions.plotsquaredv4;
|
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.util.TaskManager;
|
|
||||||
import com.github.intellectualsites.plotsquared.commands.CommandDeclaration;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.commands.CommandCategory;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.commands.RequiredType;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.commands.SubCommand;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.config.Captions;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.util.WorldUtil;
|
|
||||||
|
|
||||||
@CommandDeclaration(
|
|
||||||
command = "trimchunks",
|
|
||||||
permission = "plots.admin",
|
|
||||||
description = "Delete unmodified portions of your plotworld",
|
|
||||||
requiredType = RequiredType.PLAYER,
|
|
||||||
category = CommandCategory.ADMINISTRATION)
|
|
||||||
public class FaweTrim extends SubCommand {
|
|
||||||
|
|
||||||
private boolean ran = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCommand(final PlotPlayer plotPlayer, final String[] strings) {
|
|
||||||
if (ran) {
|
|
||||||
plotPlayer.sendMessage("Already running!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (strings.length != 2) {
|
|
||||||
plotPlayer.sendMessage(
|
|
||||||
"First make a backup of your world called <world-copy> then stand in the middle of an empty plot");
|
|
||||||
plotPlayer.sendMessage("use /plot trimall <world> <boolean-delete-unowned>");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!WorldUtil.IMP.isWorld(strings[0])) {
|
|
||||||
Captions.NOT_VALID_PLOT_WORLD.send(plotPlayer, strings[0]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ran = true;
|
|
||||||
TaskManager.IMP.async(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
// TODO NOT IMPLEMENTED
|
|
||||||
// PlotTrim trim = new PlotTrim(plotPlayer, plotPlayer.getPlotAreaAbs(), strings[0], Boolean.parseBoolean(strings[1]));
|
|
||||||
// Location loc = plotPlayer.getLocation();
|
|
||||||
// trim.setChunk(loc.getX() >> 4, loc.getZ() >> 4);
|
|
||||||
// trim.run();
|
|
||||||
// plotPlayer.sendMessage("Done!");
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
ran = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,105 +0,0 @@
|
|||||||
package com.fastasyncworldedit.bukkit.regions.plotsquaredv4;
|
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.util.TaskManager;
|
|
||||||
import com.github.intellectualsites.plotsquared.commands.Command;
|
|
||||||
import com.github.intellectualsites.plotsquared.commands.CommandDeclaration;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.commands.CommandCategory;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.commands.MainCommand;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.commands.RequiredType;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.config.Captions;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal2;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal3;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.util.Permissions;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.util.StringMan;
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
|
||||||
import com.sk89q.worldedit.extension.platform.Capability;
|
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
|
||||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
|
||||||
import com.sk89q.worldedit.world.biome.Biomes;
|
|
||||||
import com.sk89q.worldedit.world.registry.BiomeRegistry;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
|
||||||
|
|
||||||
@CommandDeclaration(
|
|
||||||
command = "generatebiome",
|
|
||||||
permission = "plots.generatebiome",
|
|
||||||
category = CommandCategory.APPEARANCE,
|
|
||||||
requiredType = RequiredType.NONE,
|
|
||||||
description = "Generate a biome in your plot",
|
|
||||||
aliases = {"bg", "gb"},
|
|
||||||
usage = "/plots generatebiome <biome>"
|
|
||||||
)
|
|
||||||
public class PlotSetBiome extends Command {
|
|
||||||
|
|
||||||
public PlotSetBiome() {
|
|
||||||
super(MainCommand.getInstance(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletableFuture<Boolean> execute(
|
|
||||||
final PlotPlayer player,
|
|
||||||
String[] args,
|
|
||||||
RunnableVal3<Command, Runnable, Runnable> confirm,
|
|
||||||
RunnableVal2<Command, CommandResult> whenDone
|
|
||||||
) throws CommandException {
|
|
||||||
final Plot plot = check(player.getCurrentPlot(), Captions.NOT_IN_PLOT);
|
|
||||||
checkTrue(plot.isOwner(player.getUUID()) || Permissions
|
|
||||||
.hasPermission(player, "plots.admin.command.generatebiome"), Captions.NO_PLOT_PERMS);
|
|
||||||
if (plot.getRunning() != 0) {
|
|
||||||
Captions.WAIT_FOR_TIMER.send(player);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
checkTrue(args.length == 1, Captions.COMMAND_SYNTAX, getUsage());
|
|
||||||
final Set<CuboidRegion> regions = plot.getRegions();
|
|
||||||
BiomeRegistry biomeRegistry = WorldEdit
|
|
||||||
.getInstance()
|
|
||||||
.getPlatformManager()
|
|
||||||
.queryCapability(Capability.GAME_HOOKS)
|
|
||||||
.getRegistries()
|
|
||||||
.getBiomeRegistry();
|
|
||||||
Collection<BiomeType> knownBiomes = BiomeTypes.values();
|
|
||||||
final BiomeType biome = Biomes.findBiomeByName(knownBiomes, args[0], biomeRegistry);
|
|
||||||
if (biome == null) {
|
|
||||||
String biomes = StringMan
|
|
||||||
.join(BiomeType.REGISTRY.values(), Captions.BLOCK_LIST_SEPARATOR.getTranslated());
|
|
||||||
Captions.NEED_BIOME.send(player);
|
|
||||||
MainUtil.sendMessage(player, Captions.SUBCOMMAND_SET_OPTIONS_HEADER + biomes);
|
|
||||||
return CompletableFuture.completedFuture(false);
|
|
||||||
}
|
|
||||||
confirm.run(this, () -> {
|
|
||||||
if (plot.getRunning() != 0) {
|
|
||||||
Captions.WAIT_FOR_TIMER.send(player);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
plot.addRunning();
|
|
||||||
TaskManager.IMP.async(() -> {
|
|
||||||
EditSession session = WorldEdit.getInstance().newEditSessionBuilder().world(BukkitAdapter.adapt(Bukkit.getWorld(
|
|
||||||
plot.getArea().worldname)))
|
|
||||||
.checkMemory(false)
|
|
||||||
.allowedRegionsEverywhere()
|
|
||||||
.actor(BukkitAdapter.adapt(Bukkit.getPlayer(player.getUUID())))
|
|
||||||
.limitUnlimited()
|
|
||||||
.build();
|
|
||||||
long seed = ThreadLocalRandom.current().nextLong();
|
|
||||||
for (CuboidRegion region : regions) {
|
|
||||||
session.regenerate(region, biome, seed);
|
|
||||||
}
|
|
||||||
session.flushQueue();
|
|
||||||
plot.removeRunning();
|
|
||||||
});
|
|
||||||
}, null);
|
|
||||||
|
|
||||||
return CompletableFuture.completedFuture(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,225 +0,0 @@
|
|||||||
package com.fastasyncworldedit.bukkit.regions.plotsquaredv4;
|
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.FaweAPI;
|
|
||||||
import com.fastasyncworldedit.core.configuration.Caption;
|
|
||||||
import com.fastasyncworldedit.core.regions.FaweMask;
|
|
||||||
import com.fastasyncworldedit.core.regions.FaweMaskManager;
|
|
||||||
import com.fastasyncworldedit.core.regions.RegionWrapper;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.commands.MainCommand;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.config.Settings;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.database.DBFunc;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.flag.Flags;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.listener.WEManager;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.util.ChunkManager;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler;
|
|
||||||
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
|
|
||||||
import com.sk89q.worldedit.entity.Player;
|
|
||||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
|
||||||
import com.sk89q.worldedit.regions.Region;
|
|
||||||
import com.sk89q.worldedit.regions.RegionIntersection;
|
|
||||||
import com.sk89q.worldedit.world.World;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class PlotSquaredFeature extends FaweMaskManager {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
|
||||||
|
|
||||||
public PlotSquaredFeature() {
|
|
||||||
super("PlotSquared");
|
|
||||||
LOGGER.info("Optimizing PlotSquared");
|
|
||||||
if (com.fastasyncworldedit.core.configuration.Settings.IMP.ENABLED_COMPONENTS.PLOTSQUARED_V4_HOOK) {
|
|
||||||
Settings.Enabled_Components.WORLDEDIT_RESTRICTIONS = false;
|
|
||||||
try {
|
|
||||||
setupBlockQueue();
|
|
||||||
setupSchematicHandler();
|
|
||||||
setupChunkManager();
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
LOGGER.info("Please update PlotSquared: https://www.spigotmc.org/resources/77506/");
|
|
||||||
}
|
|
||||||
if (Settings.PLATFORM.toLowerCase(Locale.ROOT).startsWith("bukkit")) {
|
|
||||||
new FaweTrim();
|
|
||||||
}
|
|
||||||
if (MainCommand.getInstance().getCommand("generatebiome") == null) {
|
|
||||||
new PlotSetBiome();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TODO: revisit this later on
|
|
||||||
/*
|
|
||||||
try {
|
|
||||||
if (Settings.Enabled_Components.WORLDS) {
|
|
||||||
new ReplaceAll();
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
log.debug("You need to update PlotSquared to access the CFI and REPLACEALL commands");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getName(UUID uuid) {
|
|
||||||
return UUIDHandler.getName(uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupBlockQueue() throws RuntimeException {
|
|
||||||
// If it's going to fail, throw an error now rather than later
|
|
||||||
//QueueProvider provider = QueueProvider.of(FaweLocalBlockQueue.class, null);
|
|
||||||
//GlobalBlockQueue.IMP.setProvider(provider);
|
|
||||||
//HybridPlotManager.REGENERATIVE_CLEAR = false;
|
|
||||||
//log.debug(" - QueueProvider: " + FaweLocalBlockQueue.class);
|
|
||||||
//log.debug(" - HybridPlotManager.REGENERATIVE_CLEAR: " + HybridPlotManager.REGENERATIVE_CLEAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupChunkManager() throws RuntimeException {
|
|
||||||
ChunkManager.manager = new FaweChunkManager(ChunkManager.manager);
|
|
||||||
LOGGER.info(" - ChunkManager: {}", ChunkManager.manager);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupSchematicHandler() throws RuntimeException {
|
|
||||||
SchematicHandler.manager = new FaweSchematicHandler();
|
|
||||||
LOGGER.info(" - SchematicHandler: {}", SchematicHandler.manager);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAllowed(Player player, Plot plot, MaskType type) {
|
|
||||||
if (plot == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
UUID uid = player.getUniqueId();
|
|
||||||
if (Flags.NO_WORLDEDIT.isTrue(plot)) {
|
|
||||||
player.print(Caption.of(
|
|
||||||
"fawe.cancel.reason.no.region.reason",
|
|
||||||
Caption.of("fawe.cancel.reason.no.region.plot.noworldeditflag")
|
|
||||||
));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (plot.isOwner(uid) || player.hasPermission("fawe.plotsquared.admin")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type != MaskType.MEMBER) {
|
|
||||||
player.print(Caption.of(
|
|
||||||
"fawe.cancel.reason.no.region.reason",
|
|
||||||
Caption.of("fawe.cancel.reason.no.region.plot.owner.only")
|
|
||||||
));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (plot.getTrusted().contains(uid) || plot.getTrusted().contains(DBFunc.EVERYONE)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (plot.getMembers().contains(uid) || plot.getMembers().contains(DBFunc.EVERYONE)) {
|
|
||||||
if (!player.hasPermission("fawe.plotsquared.member")) {
|
|
||||||
player.print(Caption.of(
|
|
||||||
"fawe.cancel.reason.no.region.reason",
|
|
||||||
Caption.of("fawe.error.no-perm", "fawe.plotsquared.member")
|
|
||||||
));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!plot.getOwners().isEmpty() && plot.getOwners().stream().anyMatch(this::playerOnline)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
player.print(Caption.of(
|
|
||||||
"fawe.cancel.reason.no.region.reason",
|
|
||||||
Caption.of("fawe.cancel.reason.no.region.plot.owner.offline")
|
|
||||||
));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
player.print(Caption.of(
|
|
||||||
"fawe.cancel.reason.no.region.reason",
|
|
||||||
Caption.of("fawe.cancel.reason.no.region.not.added")
|
|
||||||
));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean playerOnline(UUID uuid) {
|
|
||||||
if (uuid == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
org.bukkit.entity.Player player = Bukkit.getPlayer(uuid);
|
|
||||||
return player != null && player.isOnline();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FaweMask getMask(Player player, MaskType type) {
|
|
||||||
final PlotPlayer pp = PlotPlayer.wrap(player.getUniqueId());
|
|
||||||
if (pp == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final Set<CuboidRegion> regions;
|
|
||||||
Plot plot = pp.getCurrentPlot();
|
|
||||||
if (isAllowed(player, plot, type)) {
|
|
||||||
regions = plot.getRegions();
|
|
||||||
} else {
|
|
||||||
plot = null;
|
|
||||||
regions = WEManager.getMask(pp);
|
|
||||||
if (regions.size() == 1) {
|
|
||||||
CuboidRegion region = regions.iterator().next();
|
|
||||||
if (region.getMinimumPoint().getX() == Integer.MIN_VALUE && region
|
|
||||||
.getMaximumPoint()
|
|
||||||
.getX() == Integer.MAX_VALUE) {
|
|
||||||
regions.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (regions.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
PlotArea area = pp.getApplicablePlotArea();
|
|
||||||
int min = area != null ? area.MIN_BUILD_HEIGHT : 0;
|
|
||||||
int max = area != null ? Math.min(255, area.MAX_BUILD_HEIGHT) : 255;
|
|
||||||
final HashSet<RegionWrapper> faweRegions = new HashSet<>();
|
|
||||||
for (CuboidRegion current : regions) {
|
|
||||||
faweRegions.add(new RegionWrapper(
|
|
||||||
current.getMinimumX(),
|
|
||||||
current.getMaximumX(),
|
|
||||||
min,
|
|
||||||
max,
|
|
||||||
current.getMinimumZ(),
|
|
||||||
current.getMaximumZ()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
final CuboidRegion region = regions.iterator().next();
|
|
||||||
final BlockVector3 pos1 = BlockVector3.at(region.getMinimumX(), min, region.getMinimumZ());
|
|
||||||
final BlockVector3 pos2 = BlockVector3.at(region.getMaximumX(), max, region.getMaximumZ());
|
|
||||||
final Plot finalPlot = plot;
|
|
||||||
if (Settings.Done.RESTRICT_BUILDING && Flags.DONE.isSet(finalPlot) || regions.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Region maskedRegion;
|
|
||||||
if (regions.size() == 1) {
|
|
||||||
maskedRegion = new CuboidRegion(pos1, pos2);
|
|
||||||
} else {
|
|
||||||
World world = FaweAPI.getWorld(area.worldname);
|
|
||||||
List<Region> weRegions = regions.stream()
|
|
||||||
.map(r -> new CuboidRegion(
|
|
||||||
world,
|
|
||||||
BlockVector3.at(r.getMinimumX(), r.getMinimumY(), r.getMinimumZ()),
|
|
||||||
BlockVector3.at(r.getMaximumX(), r.getMaximumY(), r.getMaximumZ())
|
|
||||||
))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
maskedRegion = new RegionIntersection(world, weRegions);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new FaweMask(maskedRegion) {
|
|
||||||
@Override
|
|
||||||
public boolean isValid(Player player, MaskType type) {
|
|
||||||
if (Settings.Done.RESTRICT_BUILDING && Flags.DONE.isSet(finalPlot)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return isAllowed(player, finalPlot, type);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -34,7 +34,7 @@ public class BukkitItemStack extends BaseItemStack {
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public Object getNativeItem() {
|
public Object getNativeItem() {
|
||||||
ItemUtil util = Fawe.<FaweBukkit>imp().getItemUtil();
|
ItemUtil util = Fawe.<FaweBukkit>platform().getItemUtil();
|
||||||
if (util != null && nativeItem == null) {
|
if (util != null && nativeItem == null) {
|
||||||
return nativeItem = util.getNMSItem(stack);
|
return nativeItem = util.getNMSItem(stack);
|
||||||
}
|
}
|
||||||
@ -58,7 +58,7 @@ public class BukkitItemStack extends BaseItemStack {
|
|||||||
public CompoundTag getNbtData() {
|
public CompoundTag getNbtData() {
|
||||||
if (!loadedNBT) {
|
if (!loadedNBT) {
|
||||||
loadedNBT = true;
|
loadedNBT = true;
|
||||||
ItemUtil util = Fawe.<FaweBukkit>imp().getItemUtil();
|
ItemUtil util = Fawe.<FaweBukkit>platform().getItemUtil();
|
||||||
if (util != null) {
|
if (util != null) {
|
||||||
super.setNbtData(util.getNBT(stack));
|
super.setNbtData(util.getNBT(stack));
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@ public class BukkitItemStack extends BaseItemStack {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNbtData(@Nullable CompoundTag nbtData) {
|
public void setNbtData(@Nullable CompoundTag nbtData) {
|
||||||
ItemUtil util = Fawe.<FaweBukkit>imp().getItemUtil();
|
ItemUtil util = Fawe.<FaweBukkit>platform().getItemUtil();
|
||||||
if (util != null) {
|
if (util != null) {
|
||||||
stack = util.setNBT(stack, nbtData);
|
stack = util.setNBT(stack, nbtData);
|
||||||
nativeItem = null;
|
nativeItem = null;
|
||||||
|
@ -12,6 +12,7 @@ public class MinecraftVersion implements Comparable<MinecraftVersion> {
|
|||||||
|
|
||||||
public static final MinecraftVersion NETHER = new MinecraftVersion(1, 16);
|
public static final MinecraftVersion NETHER = new MinecraftVersion(1, 16);
|
||||||
public static final MinecraftVersion CAVES_17 = new MinecraftVersion(1, 17);
|
public static final MinecraftVersion CAVES_17 = new MinecraftVersion(1, 17);
|
||||||
|
public static final MinecraftVersion CAVES_18 = new MinecraftVersion(1, 18);
|
||||||
|
|
||||||
private final int major;
|
private final int major;
|
||||||
private final int minor;
|
private final int minor;
|
||||||
@ -68,7 +69,7 @@ public class MinecraftVersion implements Comparable<MinecraftVersion> {
|
|||||||
* @param other The other version to compare against.
|
* @param other The other version to compare against.
|
||||||
* @return {@code true} if this version is higher or equal compared to the other version.
|
* @return {@code true} if this version is higher or equal compared to the other version.
|
||||||
*/
|
*/
|
||||||
public boolean isEqualOrHigher(MinecraftVersion other) {
|
public boolean isEqualOrHigherThan(MinecraftVersion other) {
|
||||||
return compareTo(other) >= 0;
|
return compareTo(other) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +77,7 @@ public class MinecraftVersion implements Comparable<MinecraftVersion> {
|
|||||||
* @param other The other version to compare against.
|
* @param other The other version to compare against.
|
||||||
* @return {@code true} if this version is lower or equal compared to the other version.
|
* @return {@code true} if this version is lower or equal compared to the other version.
|
||||||
*/
|
*/
|
||||||
public boolean isEqualOrLower(MinecraftVersion other) {
|
public boolean isEqualOrLowerThan(MinecraftVersion other) {
|
||||||
return compareTo(other) <= 0;
|
return compareTo(other) <= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +85,7 @@ public class MinecraftVersion implements Comparable<MinecraftVersion> {
|
|||||||
* @param other The other version to compare against.
|
* @param other The other version to compare against.
|
||||||
* @return {@code true} if this version is higher than the other version.
|
* @return {@code true} if this version is higher than the other version.
|
||||||
*/
|
*/
|
||||||
public boolean isHigher(MinecraftVersion other) {
|
public boolean isHigherThan(MinecraftVersion other) {
|
||||||
return compareTo(other) > 0;
|
return compareTo(other) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +93,7 @@ public class MinecraftVersion implements Comparable<MinecraftVersion> {
|
|||||||
* @param other The other version to compare against.
|
* @param other The other version to compare against.
|
||||||
* @return {@code true} if this version is lower than to the other version.
|
* @return {@code true} if this version is lower than to the other version.
|
||||||
*/
|
*/
|
||||||
public boolean isLower(MinecraftVersion other) {
|
public boolean isLowerThan(MinecraftVersion other) {
|
||||||
return compareTo(other) < 0;
|
return compareTo(other) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,6 +140,11 @@ public class MinecraftVersion implements Comparable<MinecraftVersion> {
|
|||||||
return getRelease() == that.getRelease();
|
return getRelease() == that.getRelease();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return major + "." + minor + "." + release;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the server version based on the CraftBukkit package path, e.g. {@code org.bukkit.craftbukkit.v1_16_R3},
|
* Determines the server version based on the CraftBukkit package path, e.g. {@code org.bukkit.craftbukkit.v1_16_R3},
|
||||||
* where v1_16_R3 is the resolved version.
|
* where v1_16_R3 is the resolved version.
|
||||||
|
@ -107,7 +107,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
|
|||||||
this.player = player;
|
this.player = player;
|
||||||
//FAWE start
|
//FAWE start
|
||||||
this.permAttachment = plugin.getPermissionAttachmentManager().getOrAddAttachment(player);
|
this.permAttachment = plugin.getPermissionAttachmentManager().getOrAddAttachment(player);
|
||||||
if (player != null && Settings.IMP.CLIPBOARD.USE_DISK) {
|
if (player != null && Settings.settings().CLIPBOARD.USE_DISK) {
|
||||||
BukkitPlayer cached = WorldEditPlugin.getInstance().getCachedPlayer(player);
|
BukkitPlayer cached = WorldEditPlugin.getInstance().getCachedPlayer(player);
|
||||||
if (cached == null) {
|
if (cached == null) {
|
||||||
loadClipboardFromDisk();
|
loadClipboardFromDisk();
|
||||||
@ -169,7 +169,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
|
|||||||
player.getInventory().setItemInMainHand(newItem);
|
player.getInventory().setItemInMainHand(newItem);
|
||||||
HashMap<Integer, ItemStack> overflow = inv.addItem(item);
|
HashMap<Integer, ItemStack> overflow = inv.addItem(item);
|
||||||
if (!overflow.isEmpty()) {
|
if (!overflow.isEmpty()) {
|
||||||
TaskManager.IMP.sync(new RunnableVal<>() {
|
TaskManager.taskManager().sync(new RunnableVal<>() {
|
||||||
@Override
|
@Override
|
||||||
public void run(Object value) {
|
public void run(Object value) {
|
||||||
for (Map.Entry<Integer, ItemStack> entry : overflow.entrySet()) {
|
for (Map.Entry<Integer, ItemStack> entry : overflow.entrySet()) {
|
||||||
@ -243,7 +243,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
|
|||||||
}
|
}
|
||||||
org.bukkit.World finalWorld = world;
|
org.bukkit.World finalWorld = world;
|
||||||
//FAWE end
|
//FAWE end
|
||||||
return TaskManager.IMP.sync(() -> player.teleport(new Location(
|
return TaskManager.taskManager().sync(() -> player.teleport(new Location(
|
||||||
finalWorld,
|
finalWorld,
|
||||||
pos.getX(),
|
pos.getX(),
|
||||||
pos.getY(),
|
pos.getY(),
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.bukkit;
|
package com.sk89q.worldedit.bukkit;
|
||||||
|
|
||||||
|
import com.fastasyncworldedit.bukkit.util.MinecraftVersion;
|
||||||
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.sk89q.bukkit.util.CommandInfo;
|
import com.sk89q.bukkit.util.CommandInfo;
|
||||||
@ -274,9 +275,19 @@ public class BukkitServerInterface extends AbstractPlatform implements MultiUser
|
|||||||
RelighterFactory getRelighterFactory() {
|
RelighterFactory getRelighterFactory() {
|
||||||
if (this.relighterFactory == null) {
|
if (this.relighterFactory == null) {
|
||||||
this.relighterFactory = this.plugin.getBukkitImplAdapter().getRelighterFactory();
|
this.relighterFactory = this.plugin.getBukkitImplAdapter().getRelighterFactory();
|
||||||
LOGGER.info("Using " + this.relighterFactory.getClass().getCanonicalName() + " as relighter factory.");
|
LOGGER.info("Using {} as relighter factory.", this.relighterFactory.getClass().getCanonicalName());
|
||||||
}
|
}
|
||||||
return this.relighterFactory;
|
return this.relighterFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int versionMinY() {
|
||||||
|
return new MinecraftVersion().isEqualOrHigherThan(MinecraftVersion.CAVES_18) ? -64 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int versionMaxY() {
|
||||||
|
return new MinecraftVersion().isEqualOrHigherThan(MinecraftVersion.CAVES_18) ? 319 : 255;
|
||||||
|
}
|
||||||
//FAWE end
|
//FAWE end
|
||||||
}
|
}
|
||||||
|
@ -301,10 +301,10 @@ public class BukkitWorld extends AbstractWorld {
|
|||||||
if (treeTypeMapping.get(type) == null) {
|
if (treeTypeMapping.get(type) == null) {
|
||||||
LOGGER.error("No TreeType mapping for TreeGenerator.TreeType." + type);
|
LOGGER.error("No TreeType mapping for TreeGenerator.TreeType." + type);
|
||||||
//FAWE start
|
//FAWE start
|
||||||
LOGGER.info("The above message is displayed because your FAWE version is newer than " + Bukkit.getVersion() +
|
LOGGER.info("The above message is displayed because your FAWE version is newer than {}" +
|
||||||
" and contains features of future minecraft versions which do not exist in "
|
" and contains features of future minecraft versions which do not exist in {} hence the tree type" +
|
||||||
+ Bukkit.getVersion() + ", hence the tree type " + type + " is not available. This is not an error. " +
|
"{} is not available. This is not an error. This version will work on your version of Minecraft." +
|
||||||
"This version will work on your version of Minecraft. This is an informative message only");
|
"This is an informative message only.", Bukkit.getVersion(), Bukkit.getVersion(), type);
|
||||||
//FAWE end
|
//FAWE end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -317,7 +317,7 @@ public class BukkitWorld extends AbstractWorld {
|
|||||||
@Override
|
@Override
|
||||||
public boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, BlockVector3 pt) {
|
public boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, BlockVector3 pt) {
|
||||||
//FAWE start - allow tree commands to be undone and obey region restrictions
|
//FAWE start - allow tree commands to be undone and obey region restrictions
|
||||||
return TaskManager.IMP.sync(() -> WorldEditPlugin.getInstance().getBukkitImplAdapter().generateTree(type, editSession, pt,
|
return TaskManager.taskManager().sync(() -> WorldEditPlugin.getInstance().getBukkitImplAdapter().generateTree(type, editSession, pt,
|
||||||
getWorld()
|
getWorld()
|
||||||
));
|
));
|
||||||
//FAWE end
|
//FAWE end
|
||||||
@ -520,7 +520,7 @@ public class BukkitWorld extends AbstractWorld {
|
|||||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||||
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
|
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
|
||||||
if (adapter != null) {
|
if (adapter != null) {
|
||||||
return adapter.getBlock(BukkitAdapter.adapt(getWorld(), position));
|
return adapter.getFullBlock(BukkitAdapter.adapt(getWorld(), position));
|
||||||
} else {
|
} else {
|
||||||
return getBlock(position).toBaseBlock();
|
return getBlock(position).toBaseBlock();
|
||||||
}
|
}
|
||||||
@ -555,7 +555,7 @@ public class BukkitWorld extends AbstractWorld {
|
|||||||
@Override
|
@Override
|
||||||
public boolean fullySupports3DBiomes() {
|
public boolean fullySupports3DBiomes() {
|
||||||
// Supports if API does and we're not in the overworld
|
// Supports if API does and we're not in the overworld
|
||||||
return HAS_3D_BIOMES && getWorld().getEnvironment() != World.Environment.NORMAL;
|
return HAS_3D_BIOMES && getWorld().getEnvironment() != World.Environment.NORMAL || PaperLib.isVersion(18);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
|
@ -138,12 +138,12 @@ public class WorldEditPlugin extends JavaPlugin {
|
|||||||
platform = new BukkitServerInterface(this, getServer());
|
platform = new BukkitServerInterface(this, getServer());
|
||||||
worldEdit.getPlatformManager().register(platform);
|
worldEdit.getPlatformManager().register(platform);
|
||||||
|
|
||||||
//FAWE start - Rename config to config-legacy.yml TODO: Chose a better name in the future
|
//FAWE start - Migrate from config-legacy to worldedit-config
|
||||||
createDefaultConfiguration("config-legacy.yml"); // Create the default configuration file for WorldEdit, for us it's 'config-legacy.yml'
|
migrateLegacyConfig();
|
||||||
//FAWE end
|
//FAWE end
|
||||||
|
|
||||||
//FAWE start - Modify WorldEdit config name
|
//FAWE start - Modify WorldEdit config name
|
||||||
config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "config-legacy.yml"), true), this);
|
config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "worldedit-config.yml"), true), this);
|
||||||
//FAWE end
|
//FAWE end
|
||||||
|
|
||||||
//FAWE start - Setup permission attachments
|
//FAWE start - Setup permission attachments
|
||||||
@ -220,8 +220,6 @@ public class WorldEditPlugin extends JavaPlugin {
|
|||||||
// Enable metrics
|
// Enable metrics
|
||||||
new Metrics(this, BSTATS_ID);
|
new Metrics(this, BSTATS_ID);
|
||||||
|
|
||||||
// Check whether the server runs on 11 or greater
|
|
||||||
ServerLib.checkJavaLTS();
|
|
||||||
// Check if we are in a safe environment
|
// Check if we are in a safe environment
|
||||||
ServerLib.checkUnsafeForks();
|
ServerLib.checkUnsafeForks();
|
||||||
// Check if a new build is available
|
// Check if a new build is available
|
||||||
@ -369,8 +367,8 @@ public class WorldEditPlugin extends JavaPlugin {
|
|||||||
} else {
|
} else {
|
||||||
//FAWE start - Identify as FAWE
|
//FAWE start - Identify as FAWE
|
||||||
LOGGER.info("FastAsyncWorldEdit could not find a Bukkit adapter for this MC version, "
|
LOGGER.info("FastAsyncWorldEdit could not find a Bukkit adapter for this MC version, "
|
||||||
+ "but it seems that you have another implementation of FastAsyncWorldEdit installed (" + platform.getPlatformName() + ") "
|
+ "but it seems that you have another implementation of FastAsyncWorldEdit installed ({}) "
|
||||||
+ "that handles the world editing.");
|
+ "that handles the world editing.", platform.getPlatformName());
|
||||||
//FAWE end
|
//FAWE end
|
||||||
}
|
}
|
||||||
this.adapter.invalidate();
|
this.adapter.invalidate();
|
||||||
@ -382,7 +380,7 @@ public class WorldEditPlugin extends JavaPlugin {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
Fawe.get().onDisable();
|
Fawe.instance().onDisable();
|
||||||
WorldEdit worldEdit = WorldEdit.getInstance();
|
WorldEdit worldEdit = WorldEdit.getInstance();
|
||||||
worldEdit.getSessionManager().unload();
|
worldEdit.getSessionManager().unload();
|
||||||
if (platform != null) {
|
if (platform != null) {
|
||||||
@ -424,6 +422,19 @@ public class WorldEditPlugin extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void migrateLegacyConfig() {
|
||||||
|
File legacy = new File(getDataFolder(), "config-legacy.yml");
|
||||||
|
if (legacy.exists()) {
|
||||||
|
try {
|
||||||
|
legacy.renameTo(new File(getDataFolder(), "worldedit-config.yml"));
|
||||||
|
LOGGER.info("Migrated config-legacy.yml to worldedit-config.yml");
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error("Unable to rename legacy config file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
createDefaultConfiguration("worldedit-config.yml");
|
||||||
|
}
|
||||||
|
|
||||||
private void copyDefaultConfig(InputStream input, File actual, String name) {
|
private void copyDefaultConfig(InputStream input, File actual, String name) {
|
||||||
try (FileOutputStream output = new FileOutputStream(actual)) {
|
try (FileOutputStream output = new FileOutputStream(actual)) {
|
||||||
byte[] buf = new byte[8192];
|
byte[] buf = new byte[8192];
|
||||||
|
@ -106,7 +106,15 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
|
|||||||
* @param location the location
|
* @param location the location
|
||||||
* @return the block
|
* @return the block
|
||||||
*/
|
*/
|
||||||
BaseBlock getBlock(Location location);
|
BlockState getBlock(Location location);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the block at the given location.
|
||||||
|
*
|
||||||
|
* @param location the location
|
||||||
|
* @return the block
|
||||||
|
*/
|
||||||
|
BaseBlock getFullBlock(Location location);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@link WorldNativeAccess} for the given world reference.
|
* Create a {@link WorldNativeAccess} for the given world reference.
|
||||||
@ -306,7 +314,7 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
default World createWorld(WorldCreator creator) {
|
default World createWorld(WorldCreator creator) {
|
||||||
return ((FaweBukkit) Fawe.imp()).createWorldUnloaded(creator::createWorld);
|
return ((FaweBukkit) Fawe.platform()).createWorldUnloaded(creator::createWorld);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.bukkit.adapter;
|
package com.sk89q.worldedit.bukkit.adapter;
|
||||||
|
|
||||||
|
import com.fastasyncworldedit.bukkit.util.MinecraftVersion;
|
||||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||||
import com.sk89q.worldedit.util.io.Closer;
|
import com.sk89q.worldedit.util.io.Closer;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@ -39,6 +40,8 @@ public class BukkitImplLoader {
|
|||||||
|
|
||||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||||
private final List<String> adapterCandidates = new ArrayList<>();
|
private final List<String> adapterCandidates = new ArrayList<>();
|
||||||
|
private final String minorMCVersion = String.valueOf(new MinecraftVersion().getMinor());
|
||||||
|
private int zeroth = 0;
|
||||||
private String customCandidate;
|
private String customCandidate;
|
||||||
|
|
||||||
private static final String SEARCH_PACKAGE = "com.sk89q.worldedit.bukkit.adapter.impl.fawe";
|
private static final String SEARCH_PACKAGE = "com.sk89q.worldedit.bukkit.adapter.impl.fawe";
|
||||||
@ -73,6 +76,7 @@ public class BukkitImplLoader {
|
|||||||
String className = System.getProperty("worldedit.bukkit.adapter");
|
String className = System.getProperty("worldedit.bukkit.adapter");
|
||||||
if (className != null) {
|
if (className != null) {
|
||||||
customCandidate = className;
|
customCandidate = className;
|
||||||
|
zeroth = 1;
|
||||||
adapterCandidates.add(className);
|
adapterCandidates.add(className);
|
||||||
LOGGER.info("-Dworldedit.bukkit.adapter used to add " + className + " to the list of available Bukkit adapters");
|
LOGGER.info("-Dworldedit.bukkit.adapter used to add " + className + " to the list of available Bukkit adapters");
|
||||||
}
|
}
|
||||||
@ -101,7 +105,11 @@ public class BukkitImplLoader {
|
|||||||
int beginIndex = 0;
|
int beginIndex = 0;
|
||||||
int endIndex = className.length() - CLASS_SUFFIX.length();
|
int endIndex = className.length() - CLASS_SUFFIX.length();
|
||||||
className = className.substring(beginIndex, endIndex);
|
className = className.substring(beginIndex, endIndex);
|
||||||
adapterCandidates.add(className);
|
if (className.contains(minorMCVersion)) {
|
||||||
|
adapterCandidates.add(zeroth, className);
|
||||||
|
} else {
|
||||||
|
adapterCandidates.add(className);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
closer.close();
|
closer.close();
|
||||||
@ -142,7 +150,11 @@ public class BukkitImplLoader {
|
|||||||
int beginIndex = 0;
|
int beginIndex = 0;
|
||||||
int endIndex = resource.length() - CLASS_SUFFIX.length();
|
int endIndex = resource.length() - CLASS_SUFFIX.length();
|
||||||
String className = resource.substring(beginIndex, endIndex);
|
String className = resource.substring(beginIndex, endIndex);
|
||||||
adapterCandidates.add(className);
|
if (className.contains(minorMCVersion)) {
|
||||||
|
adapterCandidates.add(zeroth, className);
|
||||||
|
} else {
|
||||||
|
adapterCandidates.add(className);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,39 +10,39 @@
|
|||||||
# in categories, like "max-blocks-changed", are placed in the "limits"
|
# in categories, like "max-blocks-changed", are placed in the "limits"
|
||||||
# category.
|
# category.
|
||||||
# - If you want to check the format of this file before putting it
|
# - If you want to check the format of this file before putting it
|
||||||
# into WorldEdit, paste it into http://yaml-online-parser.appspot.com/
|
# into WorldEdit, paste it into https://yaml-online-parser.appspot.com/
|
||||||
# and see if it gives you "ERROR:".
|
# and see if it gives you "ERROR:".
|
||||||
# - Lines starting with # are comments, so they are ignored.
|
# - Lines starting with # are comments, so they are ignored.
|
||||||
# - If you want to allow blocks, make sure to change "disallowed-blocks" to []
|
# - If you want to allow blocks, make sure to change "disallowed-blocks" to []
|
||||||
#
|
#
|
||||||
|
|
||||||
limits :
|
limits:
|
||||||
max-blocks-changed :
|
max-blocks-changed:
|
||||||
# Ignored, use FAWE config limits
|
# Ignored, use FAWE config limits
|
||||||
default : -1
|
default: -1
|
||||||
maximum : -1
|
maximum: -1
|
||||||
max-polygonal-points :
|
max-polygonal-points:
|
||||||
default : -1
|
default: -1
|
||||||
maximum : 20
|
maximum: 20
|
||||||
max-radius : -1
|
max-radius: -1
|
||||||
max-super-pickaxe-size : 5
|
max-super-pickaxe-size: 5
|
||||||
max-brush-radius : 100
|
max-brush-radius: 100
|
||||||
butcher-radius :
|
butcher-radius:
|
||||||
default : -1
|
default: -1
|
||||||
maximum : -1
|
maximum: -1
|
||||||
disallowed-blocks :
|
disallowed-blocks:
|
||||||
- "minecraft:wheat"
|
- "minecraft:wheat"
|
||||||
- "minecraft:fire"
|
- "minecraft:fire"
|
||||||
- "minecraft:redstone_wire"
|
- "minecraft:redstone_wire"
|
||||||
|
|
||||||
use-inventory :
|
use-inventory:
|
||||||
enable : false
|
enable: false
|
||||||
allow-override : true
|
allow-override: true
|
||||||
creative-mode-overrides : false
|
creative-mode-overrides: false
|
||||||
|
|
||||||
logging :
|
logging:
|
||||||
log-commands : false
|
log-commands: false
|
||||||
file : worldedit.log
|
file: worldedit.log
|
||||||
# The format of custom log message. This is java general format string (java.util.Formatter). Arguments are:
|
# The format of custom log message. This is java general format string (java.util.Formatter). Arguments are:
|
||||||
# 1$ : date - a Date object representing event time of the log record.
|
# 1$ : date - a Date object representing event time of the log record.
|
||||||
# 2$ : source - a string representing the caller, if available; otherwise, the logger's name.
|
# 2$ : source - a string representing the caller, if available; otherwise, the logger's name.
|
||||||
@ -53,44 +53,44 @@ logging :
|
|||||||
# For details see:
|
# For details see:
|
||||||
# https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html
|
# https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html
|
||||||
# https://docs.oracle.com/javase/8/docs/api/java/util/logging/SimpleFormatter.html#format-java.util.logging.LogRecord-
|
# https://docs.oracle.com/javase/8/docs/api/java/util/logging/SimpleFormatter.html#format-java.util.logging.LogRecord-
|
||||||
format : "[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$s]: %5$s%6$s%n"
|
format: "[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$s]: %5$s%6$s%n"
|
||||||
|
|
||||||
super-pickaxe :
|
super-pickaxe:
|
||||||
drop-items : true
|
drop-items: true
|
||||||
many-drop-items : false
|
many-drop-items: false
|
||||||
|
|
||||||
snapshots :
|
snapshots:
|
||||||
directory :
|
directory:
|
||||||
|
|
||||||
navigation-wand :
|
navigation-wand:
|
||||||
item : minecraft:compass
|
item: minecraft:compass
|
||||||
max-distance : 100
|
max-distance: 100
|
||||||
|
|
||||||
scripting :
|
scripting:
|
||||||
timeout : 3000
|
timeout: 3000
|
||||||
dir : craftscripts
|
dir: craftscripts
|
||||||
|
|
||||||
saving :
|
saving:
|
||||||
dir : schematics
|
dir: schematics
|
||||||
|
|
||||||
files :
|
files:
|
||||||
allow-symbolic-links : false
|
allow-symbolic-links: false
|
||||||
|
|
||||||
history :
|
history:
|
||||||
size : 15
|
size: 15
|
||||||
expiration : 10
|
expiration: 10
|
||||||
|
|
||||||
calculation :
|
calculation:
|
||||||
timeout : 100
|
timeout: 100
|
||||||
|
|
||||||
debugging :
|
debugging:
|
||||||
trace-unflushed-sessions : false
|
trace-unflushed-sessions: false
|
||||||
|
|
||||||
wand-item : minecraft:wooden_axe
|
wand-item: minecraft:wooden_axe
|
||||||
shell-save-type :
|
shell-save-type:
|
||||||
no-double-slash : false
|
no-double-slash: false
|
||||||
no-op-permissions : false
|
no-op-permissions: false
|
||||||
debug : false
|
debug: false
|
||||||
show-help-on-first-use : true
|
show-help-on-first-use: true
|
||||||
server-side-cui : true
|
server-side-cui: true
|
||||||
command-block-support : false
|
command-block-support: false
|
@ -20,14 +20,14 @@ public class MinecraftVersionTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEqualOrHigher() {
|
public void testEqualOrHigher() {
|
||||||
assertTrue(latestVersion.isEqualOrHigher(new MinecraftVersion(1, 16, 3)));
|
assertTrue(latestVersion.isEqualOrHigherThan(new MinecraftVersion(1, 16, 3)));
|
||||||
assertTrue(latestVersion.isEqualOrHigher(new MinecraftVersion(1, 16, 2)));
|
assertTrue(latestVersion.isEqualOrHigherThan(new MinecraftVersion(1, 16, 2)));
|
||||||
assertFalse(latestVersion.isEqualOrHigher(new MinecraftVersion(1, 16, 4)));
|
assertFalse(latestVersion.isEqualOrHigherThan(new MinecraftVersion(1, 16, 4)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEqualOrHigherWithoutRelease() {
|
public void testEqualOrHigherWithoutRelease() {
|
||||||
assertTrue(latestVersion.isEqualOrHigher(new MinecraftVersion(1, 16)));
|
assertTrue(latestVersion.isEqualOrHigherThan(new MinecraftVersion(1, 16)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -39,15 +39,15 @@ public class MinecraftVersionTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEqualOrLower() {
|
public void testEqualOrLower() {
|
||||||
assertTrue(latestVersion.isEqualOrLower(new MinecraftVersion(1, 16, 3)));
|
assertTrue(latestVersion.isEqualOrLowerThan(new MinecraftVersion(1, 16, 3)));
|
||||||
assertTrue(latestVersion.isEqualOrLower(new MinecraftVersion(1, 16, 4)));
|
assertTrue(latestVersion.isEqualOrLowerThan(new MinecraftVersion(1, 16, 4)));
|
||||||
assertFalse(latestVersion.isEqualOrLower(new MinecraftVersion(1, 16, 2)));
|
assertFalse(latestVersion.isEqualOrLowerThan(new MinecraftVersion(1, 16, 2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testForChunkStretched() {
|
public void testForChunkStretched() {
|
||||||
assertTrue(latestVersion.isEqualOrHigher(MinecraftVersion.NETHER));
|
assertTrue(latestVersion.isEqualOrHigherThan(MinecraftVersion.NETHER));
|
||||||
assertFalse(latestVersion.isLower(new MinecraftVersion(1, 14, 2)));
|
assertFalse(latestVersion.isLowerThan(new MinecraftVersion(1, 14, 2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -118,6 +118,11 @@ public class StubServer implements Server {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSimulationDistance() {
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull
|
public @NotNull
|
||||||
String getIp() {
|
String getIp() {
|
||||||
@ -150,6 +155,26 @@ public class StubServer implements Server {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getResourcePack() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getResourcePackHash() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getResourcePackPrompt() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isResourcePackRequired() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasWhitelist() {
|
public boolean hasWhitelist() {
|
||||||
return false;
|
return false;
|
||||||
@ -465,6 +490,11 @@ public class StubServer implements Server {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getHideOnlinePlayers() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getOnlineMode() {
|
public boolean getOnlineMode() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -26,6 +26,7 @@ import com.sk89q.worldedit.entity.Player;
|
|||||||
import com.sk89q.worldedit.extension.platform.AbstractPlatform;
|
import com.sk89q.worldedit.extension.platform.AbstractPlatform;
|
||||||
import com.sk89q.worldedit.extension.platform.Capability;
|
import com.sk89q.worldedit.extension.platform.Capability;
|
||||||
import com.sk89q.worldedit.extension.platform.Preference;
|
import com.sk89q.worldedit.extension.platform.Preference;
|
||||||
|
import com.sk89q.worldedit.internal.Constants;
|
||||||
import com.sk89q.worldedit.util.SideEffect;
|
import com.sk89q.worldedit.util.SideEffect;
|
||||||
import com.sk89q.worldedit.world.DataFixer;
|
import com.sk89q.worldedit.world.DataFixer;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
@ -169,6 +170,16 @@ class CLIPlatform extends AbstractPlatform {
|
|||||||
return (_a, _b, _c) -> NullRelighter.INSTANCE;
|
return (_a, _b, _c) -> NullRelighter.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int versionMinY() {
|
||||||
|
return dataVersion >= Constants.DATA_VERSION_MC_1_18 ? -64 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int versionMaxY() {
|
||||||
|
return dataVersion >= Constants.DATA_VERSION_MC_1_18 ? 319 : 255;
|
||||||
|
}
|
||||||
|
|
||||||
public void addWorld(World world) {
|
public void addWorld(World world) {
|
||||||
worlds.add(world);
|
worlds.add(world);
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ public class CLIWorldEdit {
|
|||||||
this.commandSender = new CLICommandSender(this, LOGGER);
|
this.commandSender = new CLICommandSender(this, LOGGER);
|
||||||
this.platform = new CLIPlatform(this);
|
this.platform = new CLIPlatform(this);
|
||||||
//FAWE start - identify as Fawe
|
//FAWE start - identify as Fawe
|
||||||
LOGGER.info("FastAsyncWorldEdit CLI (version " + getInternalVersion() + ") is loaded");
|
LOGGER.info("FastAsyncWorldEdit CLI (version {}) is loaded", getInternalVersion());
|
||||||
//FAWE end
|
//FAWE end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ applyPlatformAndCoreConfiguration()
|
|||||||
dependencies {
|
dependencies {
|
||||||
constraints {
|
constraints {
|
||||||
implementation("org.yaml:snakeyaml") {
|
implementation("org.yaml:snakeyaml") {
|
||||||
version { strictly("1.28") }
|
version { strictly("1.30") }
|
||||||
because("Bukkit provides SnakeYaml")
|
because("Bukkit provides SnakeYaml")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,7 +37,6 @@ dependencies {
|
|||||||
|
|
||||||
// Plugins
|
// Plugins
|
||||||
compileOnly(libs.redprotect) { isTransitive = false }
|
compileOnly(libs.redprotect) { isTransitive = false }
|
||||||
compileOnly(libs.plotsquaredV4) { isTransitive = false }
|
|
||||||
compileOnly(libs.plotsquaredV6Core) { isTransitive = false }
|
compileOnly(libs.plotsquaredV6Core) { isTransitive = false }
|
||||||
|
|
||||||
// ensure this is on the classpath for the AP
|
// ensure this is on the classpath for the AP
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "1.5.0-RC"
|
kotlin("jvm") version "1.5.30"
|
||||||
application
|
application
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,17 +101,17 @@ public class Fawe {
|
|||||||
this.setupConfigs();
|
this.setupConfigs();
|
||||||
TaskManager.IMP = this.implementation.getTaskManager();
|
TaskManager.IMP = this.implementation.getTaskManager();
|
||||||
|
|
||||||
TaskManager.IMP.async(() -> {
|
TaskManager.taskManager().async(() -> {
|
||||||
MainUtil.deleteOlder(
|
MainUtil.deleteOlder(
|
||||||
MainUtil.getFile(this.implementation
|
MainUtil.getFile(this.implementation
|
||||||
.getDirectory(), Settings.IMP.PATHS.HISTORY),
|
.getDirectory(), Settings.settings().PATHS.HISTORY),
|
||||||
TimeUnit.DAYS.toMillis(Settings.IMP.HISTORY.DELETE_AFTER_DAYS),
|
TimeUnit.DAYS.toMillis(Settings.settings().HISTORY.DELETE_AFTER_DAYS),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
MainUtil.deleteOlder(
|
MainUtil.deleteOlder(
|
||||||
MainUtil.getFile(this.implementation
|
MainUtil.getFile(this.implementation
|
||||||
.getDirectory(), Settings.IMP.PATHS.CLIPBOARD),
|
.getDirectory(), Settings.settings().PATHS.CLIPBOARD),
|
||||||
TimeUnit.DAYS.toMillis(Settings.IMP.CLIPBOARD.DELETE_AFTER_DAYS),
|
TimeUnit.DAYS.toMillis(Settings.settings().CLIPBOARD.DELETE_AFTER_DAYS),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -123,28 +123,49 @@ public class Fawe {
|
|||||||
this.timer = new FaweTimer();
|
this.timer = new FaweTimer();
|
||||||
|
|
||||||
// Delayed worldedit setup
|
// Delayed worldedit setup
|
||||||
TaskManager.IMP.later(() -> {
|
TaskManager.taskManager().later(() -> {
|
||||||
try {
|
try {
|
||||||
WEManager.IMP.addManagers(Fawe.this.implementation.getMaskManagers());
|
WEManager.weManager().addManagers(Fawe.this.implementation.getMaskManagers());
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
TaskManager.IMP.repeat(timer, 1);
|
TaskManager.taskManager().repeat(timer, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the implementation specific class.
|
* Get the implementation specific class.
|
||||||
|
* @deprecated use {@link #platform()}
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@Deprecated(forRemoval = true, since = "2.0.0")
|
||||||
public static <T extends IFawe> T imp() {
|
public static <T extends IFawe> T imp() {
|
||||||
return instance != null ? (T) instance.implementation : null;
|
return instance != null ? (T) instance.implementation : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the implementation specific class.
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T extends IFawe> T platform() {
|
||||||
|
return instance != null ? (T) instance.implementation : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the implementation independent class.
|
||||||
|
* @deprecated use {@link #instance()}
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "2.0.0")
|
||||||
|
public static Fawe get() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the implementation independent class.
|
* Get the implementation independent class.
|
||||||
*/
|
*/
|
||||||
public static Fawe get() {
|
public static Fawe instance() {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,8 +246,8 @@ public class Fawe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
if (imp().getPreloader(false) != null) {
|
if (platform().getPreloader(false) != null) {
|
||||||
imp().getPreloader(false).cancel();
|
platform().getPreloader(false).cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,7 +317,7 @@ public class Fawe {
|
|||||||
MainUtil.copyFile(MainUtil.getJarFile(), "lang/strings.json", null);
|
MainUtil.copyFile(MainUtil.getJarFile(), "lang/strings.json", null);
|
||||||
// Setting up config.yml
|
// Setting up config.yml
|
||||||
File file = new File(this.implementation.getDirectory(), "config.yml");
|
File file = new File(this.implementation.getDirectory(), "config.yml");
|
||||||
Settings.IMP.PLATFORM = implementation.getPlatform().replace("\"", "");
|
Settings.settings().PLATFORM = implementation.getPlatform().replace("\"", "");
|
||||||
try (InputStream stream = getClass().getResourceAsStream("/fawe.properties");
|
try (InputStream stream = getClass().getResourceAsStream("/fawe.properties");
|
||||||
BufferedReader br = new BufferedReader(new InputStreamReader(stream))) {
|
BufferedReader br = new BufferedReader(new InputStreamReader(stream))) {
|
||||||
String versionString = br.readLine();
|
String versionString = br.readLine();
|
||||||
@ -304,17 +325,17 @@ public class Fawe {
|
|||||||
String dateString = br.readLine();
|
String dateString = br.readLine();
|
||||||
br.close();
|
br.close();
|
||||||
this.version = FaweVersion.tryParse(versionString, commitString, dateString);
|
this.version = FaweVersion.tryParse(versionString, commitString, dateString);
|
||||||
Settings.IMP.DATE = new Date(100 + version.year, version.month, version.day).toString();
|
Settings.settings().DATE = new Date(100 + version.year, version.month, version.day).toString();
|
||||||
Settings.IMP.BUILD = "https://ci.athion.net/job/FastAsyncWorldEdit-1.17/" + version.build;
|
Settings.settings().BUILD = "https://ci.athion.net/job/FastAsyncWorldEdit/" + version.build;
|
||||||
Settings.IMP.COMMIT = "https://github.com/IntellectualSites/FastAsyncWorldEdit/commit/" + Integer.toHexString(version.hash);
|
Settings.settings().COMMIT = "https://github.com/IntellectualSites/FastAsyncWorldEdit/commit/" + Integer.toHexString(version.hash);
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Settings.IMP.reload(file);
|
Settings.settings().reload(file);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
LOGGER.error("Failed to load config.", e);
|
LOGGER.error("Failed to load config.", e);
|
||||||
}
|
}
|
||||||
Settings.IMP.QUEUE.TARGET_SIZE = Math.max(Settings.IMP.QUEUE.TARGET_SIZE, Settings.IMP.QUEUE.PARALLEL_THREADS);
|
Settings.settings().QUEUE.TARGET_SIZE = Math.max(Settings.settings().QUEUE.TARGET_SIZE, Settings.settings().QUEUE.PARALLEL_THREADS);
|
||||||
try {
|
try {
|
||||||
byte[] in = new byte[0];
|
byte[] in = new byte[0];
|
||||||
byte[] compressed = LZ4Factory.fastestJavaInstance().fastCompressor().compress(in);
|
byte[] compressed = LZ4Factory.fastestJavaInstance().fastCompressor().compress(in);
|
||||||
@ -332,14 +353,14 @@ public class Fawe {
|
|||||||
assert (Zstd.decompress(ob, compressed) == 0);
|
assert (Zstd.decompress(ob, compressed) == 0);
|
||||||
LOGGER.info("ZSTD Compression Binding loaded successfully");
|
LOGGER.info("ZSTD Compression Binding loaded successfully");
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
if (Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL > 6 || Settings.IMP.HISTORY.COMPRESSION_LEVEL > 6) {
|
if (Settings.settings().CLIPBOARD.COMPRESSION_LEVEL > 6 || Settings.settings().HISTORY.COMPRESSION_LEVEL > 6) {
|
||||||
Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL = Math.min(6, Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL);
|
Settings.settings().CLIPBOARD.COMPRESSION_LEVEL = Math.min(6, Settings.settings().CLIPBOARD.COMPRESSION_LEVEL);
|
||||||
Settings.IMP.HISTORY.COMPRESSION_LEVEL = Math.min(6, Settings.IMP.HISTORY.COMPRESSION_LEVEL);
|
Settings.settings().HISTORY.COMPRESSION_LEVEL = Math.min(6, Settings.settings().HISTORY.COMPRESSION_LEVEL);
|
||||||
LOGGER.error("ZSTD Compression Binding Not Found.\n"
|
LOGGER.error("ZSTD Compression Binding Not Found.\n"
|
||||||
+ "FAWE will still work but compression won't work as well.", e);
|
+ "FAWE will still work but compression won't work as well.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Settings.IMP.save(file);
|
Settings.settings().save(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
public WorldEdit getWorldEdit() {
|
public WorldEdit getWorldEdit() {
|
||||||
@ -347,7 +368,7 @@ public class Fawe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setupMemoryListener() {
|
private void setupMemoryListener() {
|
||||||
if (Settings.IMP.MAX_MEMORY_PERCENT < 1 || Settings.IMP.MAX_MEMORY_PERCENT > 99) {
|
if (Settings.settings().MAX_MEMORY_PERCENT < 1 || Settings.settings().MAX_MEMORY_PERCENT > 99) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@ -371,7 +392,7 @@ public class Fawe {
|
|||||||
if (max < 0) {
|
if (max < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final long alert = (max * Settings.IMP.MAX_MEMORY_PERCENT) / 100;
|
final long alert = (max * Settings.settings().MAX_MEMORY_PERCENT) / 100;
|
||||||
mp.setUsageThreshold(alert);
|
mp.setUsageThreshold(alert);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ import com.fastasyncworldedit.core.queue.IQueueExtent;
|
|||||||
import com.fastasyncworldedit.core.queue.implementation.ParallelQueueExtent;
|
import com.fastasyncworldedit.core.queue.implementation.ParallelQueueExtent;
|
||||||
import com.fastasyncworldedit.core.regions.FaweMaskManager;
|
import com.fastasyncworldedit.core.regions.FaweMaskManager;
|
||||||
import com.fastasyncworldedit.core.regions.RegionWrapper;
|
import com.fastasyncworldedit.core.regions.RegionWrapper;
|
||||||
import com.fastasyncworldedit.core.util.EditSessionBuilder;
|
|
||||||
import com.fastasyncworldedit.core.util.MainUtil;
|
import com.fastasyncworldedit.core.util.MainUtil;
|
||||||
import com.fastasyncworldedit.core.util.MemUtil;
|
import com.fastasyncworldedit.core.util.MemUtil;
|
||||||
import com.fastasyncworldedit.core.util.TaskManager;
|
import com.fastasyncworldedit.core.util.TaskManager;
|
||||||
@ -60,24 +59,13 @@ public class FaweAPI {
|
|||||||
|
|
||||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||||
|
|
||||||
/**
|
|
||||||
* Offers a lot of options for building an EditSession.
|
|
||||||
*
|
|
||||||
* @return A new EditSessionBuilder
|
|
||||||
* @deprecated See {@link WorldEdit#newEditSessionBuilder()}
|
|
||||||
*/
|
|
||||||
@Deprecated(forRemoval = true)
|
|
||||||
public static EditSessionBuilder getEditSessionBuilder(World world) {
|
|
||||||
return new EditSessionBuilder(world);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The TaskManager has some useful methods for doing things asynchronously.
|
* The TaskManager has some useful methods for doing things asynchronously.
|
||||||
*
|
*
|
||||||
* @return TaskManager
|
* @return TaskManager
|
||||||
*/
|
*/
|
||||||
public static TaskManager getTaskManager() {
|
public static TaskManager getTaskManager() {
|
||||||
return TaskManager.IMP;
|
return TaskManager.taskManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -93,7 +81,7 @@ public class FaweAPI {
|
|||||||
* @return the queue extent
|
* @return the queue extent
|
||||||
*/
|
*/
|
||||||
public static IQueueExtent<IQueueChunk> createQueue(World world, boolean autoQueue) {
|
public static IQueueExtent<IQueueChunk> createQueue(World world, boolean autoQueue) {
|
||||||
IQueueExtent<IQueueChunk> queue = Fawe.get().getQueueHandler().getQueue(world);
|
IQueueExtent<IQueueChunk> queue = Fawe.instance().getQueueHandler().getQueue(world);
|
||||||
if (!autoQueue) {
|
if (!autoQueue) {
|
||||||
queue.disableQueue();
|
queue.disableQueue();
|
||||||
}
|
}
|
||||||
@ -139,7 +127,7 @@ public class FaweAPI {
|
|||||||
* @return Set of FaweMaskManager
|
* @return Set of FaweMaskManager
|
||||||
*/
|
*/
|
||||||
public static Set<FaweMaskManager> getMaskManagers() {
|
public static Set<FaweMaskManager> getMaskManagers() {
|
||||||
return new HashSet<>(WEManager.IMP.getManagers());
|
return new HashSet<>(WEManager.weManager().getManagers());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -155,7 +143,7 @@ public class FaweAPI {
|
|||||||
* Get a player's allowed WorldEdit region(s).
|
* Get a player's allowed WorldEdit region(s).
|
||||||
*/
|
*/
|
||||||
public static Region[] getRegions(Player player) {
|
public static Region[] getRegions(Player player) {
|
||||||
return WEManager.IMP.getMask(player);
|
return WEManager.weManager().getMask(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -167,7 +155,7 @@ public class FaweAPI {
|
|||||||
* @return array of allowed regions if whitelist, else of disallowed regions.
|
* @return array of allowed regions if whitelist, else of disallowed regions.
|
||||||
*/
|
*/
|
||||||
public static Region[] getRegions(Player player, FaweMaskManager.MaskType type, boolean isWhiteList) {
|
public static Region[] getRegions(Player player, FaweMaskManager.MaskType type, boolean isWhiteList) {
|
||||||
return WEManager.IMP.getMask(player, type, isWhiteList);
|
return WEManager.weManager().getMask(player, type, isWhiteList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -182,13 +170,13 @@ public class FaweAPI {
|
|||||||
*/
|
*/
|
||||||
public static void cancelEdit(AbstractDelegateExtent extent, Component reason) {
|
public static void cancelEdit(AbstractDelegateExtent extent, Component reason) {
|
||||||
try {
|
try {
|
||||||
WEManager.IMP.cancelEdit(extent, new FaweException(reason));
|
WEManager.weManager().cancelEdit(extent, new FaweException(reason));
|
||||||
} catch (WorldEditException ignored) {
|
} catch (WorldEditException ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addMaskManager(FaweMaskManager maskMan) {
|
public static void addMaskManager(FaweMaskManager maskMan) {
|
||||||
WEManager.IMP.addManager(maskMan);
|
WEManager.weManager().addManager(maskMan);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -198,7 +186,7 @@ public class FaweAPI {
|
|||||||
if (!file.exists() || file.isDirectory()) {
|
if (!file.exists() || file.isDirectory()) {
|
||||||
throw new IllegalArgumentException("Not a file!");
|
throw new IllegalArgumentException("Not a file!");
|
||||||
}
|
}
|
||||||
if (Settings.IMP.HISTORY.USE_DISK) {
|
if (Settings.settings().HISTORY.USE_DISK) {
|
||||||
throw new IllegalArgumentException("History on disk not enabled!");
|
throw new IllegalArgumentException("History on disk not enabled!");
|
||||||
}
|
}
|
||||||
if (!file.getName().toLowerCase(Locale.ROOT).endsWith(".bd")) {
|
if (!file.getName().toLowerCase(Locale.ROOT).endsWith(".bd")) {
|
||||||
@ -236,11 +224,10 @@ public class FaweAPI {
|
|||||||
*/
|
*/
|
||||||
public static List<DiskStorageHistory> getBDFiles(Location origin, UUID user, int radius, long timediff, boolean shallow) {
|
public static List<DiskStorageHistory> getBDFiles(Location origin, UUID user, int radius, long timediff, boolean shallow) {
|
||||||
Extent extent = origin.getExtent();
|
Extent extent = origin.getExtent();
|
||||||
if (!(extent instanceof World)) {
|
if (!(extent instanceof World world)) {
|
||||||
throw new IllegalArgumentException("Origin is not a valid world");
|
throw new IllegalArgumentException("Origin is not a valid world");
|
||||||
}
|
}
|
||||||
World world = (World) extent;
|
File history = MainUtil.getFile(Fawe.platform().getDirectory(), Settings.settings().PATHS.HISTORY + File.separator + world.getName());
|
||||||
File history = MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.HISTORY + File.separator + world.getName());
|
|
||||||
if (!history.exists()) {
|
if (!history.exists()) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
@ -364,12 +351,12 @@ public class FaweAPI {
|
|||||||
World unwrapped = WorldWrapper.unwrap(world);
|
World unwrapped = WorldWrapper.unwrap(world);
|
||||||
if (unwrapped instanceof IQueueExtent) {
|
if (unwrapped instanceof IQueueExtent) {
|
||||||
queue = (IQueueExtent) unwrapped;
|
queue = (IQueueExtent) unwrapped;
|
||||||
} else if (Settings.IMP.QUEUE.PARALLEL_THREADS > 1) {
|
} else if (Settings.settings().QUEUE.PARALLEL_THREADS > 1) {
|
||||||
ParallelQueueExtent parallel =
|
ParallelQueueExtent parallel =
|
||||||
new ParallelQueueExtent(Fawe.get().getQueueHandler(), world, true);
|
new ParallelQueueExtent(Fawe.instance().getQueueHandler(), world, true);
|
||||||
queue = parallel.getExtent();
|
queue = parallel.getExtent();
|
||||||
} else {
|
} else {
|
||||||
queue = Fawe.get().getQueueHandler().getQueue(world);
|
queue = Fawe.instance().getQueueHandler().getQueue(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,7 +371,7 @@ public class FaweAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mode != RelightMode.NONE) {
|
if (mode != RelightMode.NONE) {
|
||||||
if (Settings.IMP.LIGHTING.REMOVE_FIRST) {
|
if (Settings.settings().LIGHTING.REMOVE_FIRST) {
|
||||||
relighter.removeAndRelight(true);
|
relighter.removeAndRelight(true);
|
||||||
} else {
|
} else {
|
||||||
relighter.fixSkyLighting();
|
relighter.fixSkyLighting();
|
||||||
|
@ -59,7 +59,15 @@ import java.util.function.Supplier;
|
|||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
public enum FaweCache implements Trimable {
|
public enum FaweCache implements Trimable {
|
||||||
IMP; // singleton
|
/**
|
||||||
|
* @deprecated Use {@link #INSTANCE} to get an instance.
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "2.0.0")
|
||||||
|
IMP,
|
||||||
|
/**
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
INSTANCE;
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||||
|
|
||||||
@ -301,7 +309,7 @@ public enum FaweCache implements Trimable {
|
|||||||
|
|
||||||
// BlockStates
|
// BlockStates
|
||||||
int bitsPerEntry = MathMan.log2nlz(num_palette - 1);
|
int bitsPerEntry = MathMan.log2nlz(num_palette - 1);
|
||||||
if (Settings.IMP.PROTOCOL_SUPPORT_FIX || num_palette != 1) {
|
if (Settings.settings().PROTOCOL_SUPPORT_FIX || num_palette != 1) {
|
||||||
bitsPerEntry = Math.max(bitsPerEntry, 4); // Protocol support breaks <4 bits per entry
|
bitsPerEntry = Math.max(bitsPerEntry, 4); // Protocol support breaks <4 bits per entry
|
||||||
} else {
|
} else {
|
||||||
bitsPerEntry = Math.max(bitsPerEntry, 1); // For some reason minecraft needs 4096 bits to store 0 entries
|
bitsPerEntry = Math.max(bitsPerEntry, 1); // For some reason minecraft needs 4096 bits to store 0 entries
|
||||||
@ -387,7 +395,7 @@ public enum FaweCache implements Trimable {
|
|||||||
|
|
||||||
// BlockStates
|
// BlockStates
|
||||||
int bitsPerEntry = MathMan.log2nlz(num_palette - 1);
|
int bitsPerEntry = MathMan.log2nlz(num_palette - 1);
|
||||||
if (Settings.IMP.PROTOCOL_SUPPORT_FIX || num_palette != 1) {
|
if (Settings.settings().PROTOCOL_SUPPORT_FIX || num_palette != 1) {
|
||||||
bitsPerEntry = Math.max(bitsPerEntry, 4); // Protocol support breaks <4 bits per entry
|
bitsPerEntry = Math.max(bitsPerEntry, 4); // Protocol support breaks <4 bits per entry
|
||||||
} else {
|
} else {
|
||||||
bitsPerEntry = Math.max(bitsPerEntry, 1); // For some reason minecraft needs 4096 bits to store 0 entries
|
bitsPerEntry = Math.max(bitsPerEntry, 1); // For some reason minecraft needs 4096 bits to store 0 entries
|
||||||
@ -568,7 +576,7 @@ public enum FaweCache implements Trimable {
|
|||||||
Thread stuff
|
Thread stuff
|
||||||
*/
|
*/
|
||||||
public ThreadPoolExecutor newBlockingExecutor() {
|
public ThreadPoolExecutor newBlockingExecutor() {
|
||||||
int nThreads = Settings.IMP.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,
|
||||||
@ -609,7 +617,7 @@ public enum FaweCache implements Trimable {
|
|||||||
lastException = hash;
|
lastException = hash;
|
||||||
LOGGER.catching(throwable);
|
LOGGER.catching(throwable);
|
||||||
count = 0;
|
count = 0;
|
||||||
} else if (count < Settings.IMP.QUEUE.PARALLEL_THREADS) {
|
} else if (count < Settings.settings().QUEUE.PARALLEL_THREADS) {
|
||||||
LOGGER.warn(throwable.getMessage());
|
LOGGER.warn(throwable.getMessage());
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
package com.fastasyncworldedit.core;
|
package com.fastasyncworldedit.core;
|
||||||
|
|
||||||
|
import com.fastasyncworldedit.core.util.StringMan;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An internal FAWE class not meant for public use.
|
* An internal FAWE class not meant for public use.
|
||||||
**/
|
**/
|
||||||
@ -10,28 +14,35 @@ public class FaweVersion {
|
|||||||
public final int day;
|
public final int day;
|
||||||
public final int hash;
|
public final int hash;
|
||||||
public final int build;
|
public final int build;
|
||||||
|
public final int[] semver;
|
||||||
|
public final boolean snapshot;
|
||||||
|
|
||||||
public FaweVersion(int year, int month, int day, int hash, int build) {
|
public FaweVersion(int year, int month, int day, int[] semver, boolean snapshot, int hash, int build) {
|
||||||
this.year = year;
|
this.year = year;
|
||||||
this.month = month;
|
this.month = month;
|
||||||
this.day = day;
|
this.day = day;
|
||||||
this.hash = hash;
|
this.hash = hash;
|
||||||
this.build = build;
|
this.build = build;
|
||||||
|
this.semver = semver;
|
||||||
|
this.snapshot = snapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FaweVersion(String version, String commit, String date) {
|
public FaweVersion(String version, String commit, String date) {
|
||||||
String[] split = version.substring(version.indexOf('=') + 1).split("-");
|
String[] split = version.substring(version.indexOf('=') + 1).split("-");
|
||||||
int build = 0;
|
String[] split1 = split[0].split("\\.");
|
||||||
try {
|
int[] ver = new int[3];
|
||||||
build = Integer.parseInt(split[1]);
|
for (int i = 0; i < 3; i++) {
|
||||||
} catch (NumberFormatException ignored) {
|
ver[i] = Integer.parseInt(split1[i]);
|
||||||
}
|
}
|
||||||
this.build = build;
|
this.semver = ver;
|
||||||
|
this.snapshot = split.length > 1 && split[1].toLowerCase(Locale.ROOT).contains("snapshot");
|
||||||
|
int buildIndex = this.snapshot ? 2 : 1;
|
||||||
|
this.build = split.length == buildIndex + 1 ? Integer.parseInt(split[buildIndex]) : 0;
|
||||||
this.hash = Integer.parseInt(commit.substring(commit.indexOf('=') + 1), 16);
|
this.hash = Integer.parseInt(commit.substring(commit.indexOf('=') + 1), 16);
|
||||||
String[] split1 = date.substring(date.indexOf('=') + 1).split("\\.");
|
String[] split2 = date.substring(date.indexOf('=') + 1).split("\\.");
|
||||||
this.year = Integer.parseInt(split1[0]);
|
this.year = Integer.parseInt(split2[0]);
|
||||||
this.month = Integer.parseInt(split1[1]);
|
this.month = Integer.parseInt(split2[1]);
|
||||||
this.day = Integer.parseInt(split1[2]);
|
this.day = Integer.parseInt(split2[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FaweVersion tryParse(String version, String commit, String date) {
|
public static FaweVersion tryParse(String version, String commit, String date) {
|
||||||
@ -39,28 +50,42 @@ public class FaweVersion {
|
|||||||
return new FaweVersion(version, commit, date);
|
return new FaweVersion(version, commit, date);
|
||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
exception.printStackTrace();
|
exception.printStackTrace();
|
||||||
return new FaweVersion(0, 0, 0, 0, 0);
|
return new FaweVersion(0, 0, 0, null, true, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (hash == 0 && build == 0) {
|
if (semver == null) {
|
||||||
return getSimpleVersionName() + "-NoVer-SNAPSHOT";
|
return "FastAsyncWorldEdit-NoVer-SNAPSHOT";
|
||||||
} else {
|
} else {
|
||||||
return getSimpleVersionName() + "-" + build;
|
String snapshot = this.snapshot ? "-SNAPSHOT" : "";
|
||||||
|
String build = this.build > 0 ? "-" + this.build : "";
|
||||||
|
return "FastAsyncWorldEdit-" + StringMan.join(semver, ".") + snapshot + build;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The qualified version name
|
* Returns if another FaweVersion is newer than this one
|
||||||
*/
|
*/
|
||||||
public String getSimpleVersionName() {
|
|
||||||
return "FastAsyncWorldEdit-1.17";
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isNewer(FaweVersion other) {
|
public boolean isNewer(FaweVersion other) {
|
||||||
return other.build < this.build;
|
if (other.semver == null) {
|
||||||
|
return other.build > this.build;
|
||||||
|
}
|
||||||
|
if (this.semver == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (other.semver[0] != this.semver[0]) {
|
||||||
|
return other.semver[0] > this.semver[0];
|
||||||
|
} else if (other.semver[1] != this.semver[1]) {
|
||||||
|
return other.semver[1] > this.semver[1];
|
||||||
|
} else if (other.semver[2] != this.semver[2]) {
|
||||||
|
return other.semver[2] > this.semver[2];
|
||||||
|
}
|
||||||
|
if (other.snapshot == this.snapshot) {
|
||||||
|
return other.build > this.build;
|
||||||
|
}
|
||||||
|
return !other.snapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -531,7 +531,7 @@ public class AnvilCommands {
|
|||||||
// });
|
// });
|
||||||
// if (useData) {
|
// if (useData) {
|
||||||
// for (long[] c : map) {
|
// for (long[] c : map) {
|
||||||
// BaseBlock block = FaweCache.IMP.CACHE_BLOCK[(int) c[0]];
|
// BaseBlock block = FaweCache.INSTANCE.CACHE_BLOCK[(int) c[0]];
|
||||||
// String name = BlockType.fromID(block.getId()).getName();
|
// String name = BlockType.fromID(block.getId()).getName();
|
||||||
// String str = String.format("%-7s (%.3f%%) %s #%d:%d",
|
// String str = String.format("%-7s (%.3f%%) %s #%d:%d",
|
||||||
// String.valueOf(c[1]),
|
// String.valueOf(c[1]),
|
||||||
|
@ -147,7 +147,7 @@
|
|||||||
// CFISettings settings = getSettings(player).remove();
|
// CFISettings settings = getSettings(player).remove();
|
||||||
// generator.setPacketViewer(player);
|
// generator.setPacketViewer(player);
|
||||||
// settings.setGenerator(generator).bind();
|
// settings.setGenerator(generator).bind();
|
||||||
// generator.setImageViewer(Fawe.imp().getImageViewer(player));
|
// generator.setImageViewer(Fawe.platform().getImageViewer(player));
|
||||||
// generator.update();
|
// generator.update();
|
||||||
// mainMenu(player);
|
// mainMenu(player);
|
||||||
// }
|
// }
|
||||||
@ -226,7 +226,7 @@
|
|||||||
// World world = FaweAPI.getWorld(folder.getName());
|
// World world = FaweAPI.getWorld(folder.getName());
|
||||||
// if (world != null) {
|
// if (world != null) {
|
||||||
// if (player.getWorld() != world) {
|
// if (player.getWorld() != world) {
|
||||||
// TaskManager.IMP.sync(new RunnableVal<Object>() {
|
// TaskManager.taskManager().sync(new RunnableVal<Object>() {
|
||||||
// @Override
|
// @Override
|
||||||
// public void run(Object value) {
|
// public void run(Object value) {
|
||||||
// Location spawn = new Location(world, world.getSpawnPosition().toVector3());
|
// Location spawn = new Location(world, world.getSpawnPosition().toVector3());
|
||||||
@ -425,7 +425,7 @@
|
|||||||
// switch (argOpt.toLowerCase(Locale.ROOT)) {
|
// switch (argOpt.toLowerCase(Locale.ROOT)) {
|
||||||
// case "true":
|
// case "true":
|
||||||
// case "*": {
|
// case "*": {
|
||||||
// generator.setTextureUtil(Fawe.get().getTextureUtil());
|
// generator.setTextureUtil(Fawe.instance().getTextureUtil());
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
// case "#clipboard": {
|
// case "#clipboard": {
|
||||||
@ -453,7 +453,7 @@
|
|||||||
// parserContext.setExtent(extent);
|
// parserContext.setExtent(extent);
|
||||||
// Request.request().setExtent(extent);
|
// Request.request().setExtent(extent);
|
||||||
// Mask mask = worldEdit.getMaskFactory().parseFromInput(argOpt, parserContext);
|
// Mask mask = worldEdit.getMaskFactory().parseFromInput(argOpt, parserContext);
|
||||||
// TextureUtil tu = Fawe.get().getTextureUtil();
|
// TextureUtil tu = Fawe.instance().getTextureUtil();
|
||||||
// for (int typeId : tu.getValidBlockIds()) {
|
// for (int typeId : tu.getValidBlockIds()) {
|
||||||
// BlockType type = BlockTypes.get(typeId);
|
// BlockType type = BlockTypes.get(typeId);
|
||||||
// extent.init(0, 0, 0, type.getDefaultState().toBaseBlock());
|
// extent.init(0, 0, 0, type.getDefaultState().toBaseBlock());
|
||||||
@ -464,7 +464,7 @@
|
|||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// generator.setTextureUtil(new FilteredTextureUtil(Fawe.get().getTextureUtil(), blocks));
|
// generator.setTextureUtil(new FilteredTextureUtil(Fawe.instance().getTextureUtil(), blocks));
|
||||||
// coloring(player);
|
// coloring(player);
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
@ -493,9 +493,9 @@
|
|||||||
// public void complexity(Player player, int min, int max) throws FileNotFoundException {
|
// public void complexity(Player player, int min, int max) throws FileNotFoundException {
|
||||||
// HeightMapMCAGenerator gen = assertSettings(player).getGenerator();
|
// HeightMapMCAGenerator gen = assertSettings(player).getGenerator();
|
||||||
// if (min == 0 && max == 100) {
|
// if (min == 0 && max == 100) {
|
||||||
// gen.setTextureUtil(Fawe.get().getTextureUtil());
|
// gen.setTextureUtil(Fawe.instance().getTextureUtil());
|
||||||
// } else {
|
// } else {
|
||||||
// gen.setTextureUtil(new CleanTextureUtil(Fawe.get().getTextureUtil(), min, max));
|
// gen.setTextureUtil(new CleanTextureUtil(Fawe.instance().getTextureUtil(), min, max));
|
||||||
// }
|
// }
|
||||||
// coloring(player);
|
// coloring(player);
|
||||||
// }
|
// }
|
||||||
@ -1201,7 +1201,7 @@
|
|||||||
// whiteOnly = true;
|
// whiteOnly = true;
|
||||||
// maskArg = null;
|
// maskArg = null;
|
||||||
// imageMaskArg = null;
|
// imageMaskArg = null;
|
||||||
// generator.setTextureUtil(Fawe.get().getTextureUtil());
|
// generator.setTextureUtil(Fawe.instance().getTextureUtil());
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// public void resetComponent() {
|
// public void resetComponent() {
|
||||||
|
@ -95,7 +95,7 @@ public class ListFilters {
|
|||||||
}
|
}
|
||||||
String firstArg = finalArg.substring(0, finalArg.length() - File.separator.length());
|
String firstArg = finalArg.substring(0, finalArg.length() - File.separator.length());
|
||||||
if (firstArg.length() > 3 && firstArg.length() <= 16) {
|
if (firstArg.length() > 3 && firstArg.length() <= 16) {
|
||||||
UUID fromName = Fawe.imp().getUUID(finalArg);
|
UUID fromName = Fawe.platform().getUUID(finalArg);
|
||||||
if (fromName != null) {
|
if (fromName != null) {
|
||||||
newRoot = new File(root, finalArg);
|
newRoot = new File(root, finalArg);
|
||||||
if (newRoot.exists()) {
|
if (newRoot.exists()) {
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
// PlotPlayer player = PlotPlayer.get(actor.getName());
|
// PlotPlayer player = PlotPlayer.get(actor.getName());
|
||||||
//
|
//
|
||||||
// actor.print("Claiming world");
|
// actor.print("Claiming world");
|
||||||
// Plot plot = TaskManager.IMP.sync(new RunnableVal<Plot>() {
|
// Plot plot = TaskManager.taskManager().sync(new RunnableVal<Plot>() {
|
||||||
// @Override
|
// @Override
|
||||||
// public void run(Plot o) {
|
// public void run(Plot o) {
|
||||||
// int currentPlots = Settings.Limit.GLOBAL ? player.getPlotCount()
|
// int currentPlots = Settings.Limit.GLOBAL ? player.getPlotCount()
|
||||||
@ -73,7 +73,7 @@
|
|||||||
// File folder = CFICommands.getFolder(plot.getWorldName());
|
// File folder = CFICommands.getFolder(plot.getWorldName());
|
||||||
// Boolean result = createTask.apply(folder);
|
// Boolean result = createTask.apply(folder);
|
||||||
// if (result == Boolean.TRUE) {
|
// if (result == Boolean.TRUE) {
|
||||||
// TaskManager.IMP.sync(() -> plot.teleportPlayer(player));
|
// TaskManager.taskManager().sync(() -> plot.teleportPlayer(player));
|
||||||
// }
|
// }
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
|
@ -90,7 +90,7 @@ public class BrushSettings {
|
|||||||
// }
|
// }
|
||||||
// if (settings.containsKey(SettingType.TRANSFORM.name())) {
|
// if (settings.containsKey(SettingType.TRANSFORM.name())) {
|
||||||
// String transformArgs = (String) settings.get(SettingType.TRANSFORM.name());
|
// String transformArgs = (String) settings.get(SettingType.TRANSFORM.name());
|
||||||
// ResettableExtent extent = Fawe.get().getTransformParser().parseFromInput(transformArgs, parserContext);
|
// ResettableExtent extent = Fawe.instance().getTransformParser().parseFromInput(transformArgs, parserContext);
|
||||||
// bs.setTransform(extent);
|
// bs.setTransform(extent);
|
||||||
// bs.constructor.put(SettingType.TRANSFORM, transformArgs);
|
// bs.constructor.put(SettingType.TRANSFORM, transformArgs);
|
||||||
// }
|
// }
|
||||||
|
@ -68,7 +68,7 @@ public class InspectBrush extends BrushTool {
|
|||||||
player.print(Caption.of("fawe.error.no-perm", "worldedit.tool.inspect"));
|
player.print(Caption.of("fawe.error.no-perm", "worldedit.tool.inspect"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!Settings.IMP.HISTORY.USE_DATABASE) {
|
if (!Settings.settings().HISTORY.USE_DATABASE) {
|
||||||
player.print(Caption.of(
|
player.print(Caption.of(
|
||||||
"fawe.error.setting.disable",
|
"fawe.error.setting.disable",
|
||||||
"history.use-database (Import with /history import )"
|
"history.use-database (Import with /history import )"
|
||||||
@ -81,7 +81,7 @@ public class InspectBrush extends BrushTool {
|
|||||||
final int y = target.getBlockY();
|
final int y = target.getBlockY();
|
||||||
final int z = target.getBlockZ();
|
final int z = target.getBlockZ();
|
||||||
World world = player.getWorld();
|
World world = player.getWorld();
|
||||||
RollbackDatabase db = DBHandler.IMP.getDatabase(world);
|
RollbackDatabase db = DBHandler.dbHandler().getDatabase(world);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (Supplier<RollbackOptimizedHistory> supplier : db.getEdits(target, false)) {
|
for (Supplier<RollbackOptimizedHistory> supplier : db.getEdits(target, false)) {
|
||||||
count++;
|
count++;
|
||||||
@ -95,7 +95,7 @@ public class InspectBrush extends BrushTool {
|
|||||||
int from = change.from;
|
int from = change.from;
|
||||||
int to = change.to;
|
int to = change.to;
|
||||||
UUID uuid = edit.getUUID();
|
UUID uuid = edit.getUUID();
|
||||||
String name = Fawe.imp().getName(uuid);
|
String name = Fawe.platform().getName(uuid);
|
||||||
int index = edit.getIndex();
|
int index = edit.getIndex();
|
||||||
long age = System.currentTimeMillis() - edit.getBDFile().lastModified();
|
long age = System.currentTimeMillis() - edit.getBDFile().lastModified();
|
||||||
String ageFormatted = MainUtil.secToTime(age / 1000);
|
String ageFormatted = MainUtil.secToTime(age / 1000);
|
||||||
|
@ -34,7 +34,7 @@ public class Config {
|
|||||||
/**
|
/**
|
||||||
* Get the value for a node. Probably throws some error if you try to get a non-existent key.
|
* Get the value for a node. Probably throws some error if you try to get a non-existent key.
|
||||||
*/
|
*/
|
||||||
private <T> T get(String key, Class root) {
|
private <T> T get(String key, Class<?> root) {
|
||||||
String[] split = key.split("\\.");
|
String[] split = key.split("\\.");
|
||||||
Object instance = getInstance(split, root);
|
Object instance = getInstance(split, root);
|
||||||
if (instance != null) {
|
if (instance != null) {
|
||||||
@ -57,7 +57,7 @@ public class Config {
|
|||||||
* @param key config node
|
* @param key config node
|
||||||
* @param value value
|
* @param value value
|
||||||
*/
|
*/
|
||||||
private void set(String key, Object value, Class root) {
|
private void set(String key, Object value, Class<?> root) {
|
||||||
String[] split = key.split("\\.");
|
String[] split = key.split("\\.");
|
||||||
Object instance = getInstance(split, root);
|
Object instance = getInstance(split, root);
|
||||||
if (instance != null) {
|
if (instance != null) {
|
||||||
@ -201,7 +201,7 @@ public class Config {
|
|||||||
/**
|
/**
|
||||||
* Get the static fields in a section.
|
* Get the static fields in a section.
|
||||||
*/
|
*/
|
||||||
private Map<String, Object> getFields(Class clazz) {
|
private Map<String, Object> getFields(Class<?> clazz) {
|
||||||
HashMap<String, Object> map = new HashMap<>();
|
HashMap<String, Object> map = new HashMap<>();
|
||||||
for (Field field : clazz.getFields()) {
|
for (Field field : clazz.getFields()) {
|
||||||
if (Modifier.isStatic(field.getModifiers())) {
|
if (Modifier.isStatic(field.getModifiers())) {
|
||||||
@ -223,12 +223,11 @@ public class Config {
|
|||||||
}
|
}
|
||||||
StringBuilder m = new StringBuilder();
|
StringBuilder m = new StringBuilder();
|
||||||
for (Object obj : listValue) {
|
for (Object obj : listValue) {
|
||||||
m.append(System.lineSeparator() + spacing + "- " + toYamlString(obj, spacing));
|
m.append(System.lineSeparator()).append(spacing).append("- ").append(toYamlString(obj, spacing));
|
||||||
}
|
}
|
||||||
return m.toString();
|
return m.toString();
|
||||||
}
|
}
|
||||||
if (value instanceof String) {
|
if (value instanceof String stringValue) {
|
||||||
String stringValue = (String) value;
|
|
||||||
if (stringValue.isEmpty()) {
|
if (stringValue.isEmpty()) {
|
||||||
return "''";
|
return "''";
|
||||||
}
|
}
|
||||||
@ -237,11 +236,11 @@ public class Config {
|
|||||||
return value != null ? value.toString() : "null";
|
return value != null ? value.toString() : "null";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void save(PrintWriter writer, Class clazz, final Object instance, int indent) {
|
private void save(PrintWriter writer, Class<?> clazz, final Object instance, int indent) {
|
||||||
try {
|
try {
|
||||||
String CTRF = System.lineSeparator();
|
String CTRF = System.lineSeparator();
|
||||||
String spacing = StringMan.repeat(" ", indent);
|
String spacing = StringMan.repeat(" ", indent);
|
||||||
HashMap<Class, Object> instances = new HashMap<>();
|
HashMap<Class<?>, Object> instances = new HashMap<>();
|
||||||
for (Field field : clazz.getFields()) {
|
for (Field field : clazz.getFields()) {
|
||||||
if (field.getAnnotation(Ignore.class) != null) {
|
if (field.getAnnotation(Ignore.class) != null) {
|
||||||
continue;
|
continue;
|
||||||
@ -272,7 +271,7 @@ public class Config {
|
|||||||
configBlock = new ConfigBlock();
|
configBlock = new ConfigBlock();
|
||||||
field.set(instance, configBlock);
|
field.set(instance, configBlock);
|
||||||
for (String blockName : blockNames.value()) {
|
for (String blockName : blockNames.value()) {
|
||||||
configBlock.put(blockName, current.newInstance());
|
configBlock.put(blockName, current.getDeclaredConstructor().newInstance());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Save each instance
|
// Save each instance
|
||||||
@ -299,11 +298,10 @@ public class Config {
|
|||||||
}
|
}
|
||||||
writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF);
|
writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
field.set(instance, value = current.newInstance());
|
field.set(instance, value = current.getDeclaredConstructor().newInstance());
|
||||||
instances.put(current, value);
|
instances.put(current, value);
|
||||||
}
|
}
|
||||||
save(writer, current, value, indent + 2);
|
save(writer, current, value, indent + 2);
|
||||||
continue;
|
|
||||||
} else {
|
} else {
|
||||||
writer.write(spacing + toNodeName(field.getName() + ": ") + toYamlString(
|
writer.write(spacing + toNodeName(field.getName() + ": ") + toYamlString(
|
||||||
field.get(instance),
|
field.get(instance),
|
||||||
@ -321,7 +319,7 @@ public class Config {
|
|||||||
*
|
*
|
||||||
* @param split the node (split by period)
|
* @param split the node (split by period)
|
||||||
*/
|
*/
|
||||||
private Field getField(String[] split, Class root) {
|
private Field getField(String[] split, Class<?> root) {
|
||||||
Object instance = getInstance(split, root);
|
Object instance = getInstance(split, root);
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -352,74 +350,64 @@ public class Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object getInstance(Object instance, Class clazz) throws IllegalAccessException, InstantiationException {
|
|
||||||
try {
|
|
||||||
Field instanceField = clazz.getDeclaredField(clazz.getSimpleName());
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
return clazz.newInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the instance for a specific config node.
|
* Get the instance for a specific config node.
|
||||||
*
|
*
|
||||||
* @param split the node (split by period)
|
* @param split the node (split by period)
|
||||||
* @return The instance or null
|
* @return The instance or null
|
||||||
*/
|
*/
|
||||||
private Object getInstance(String[] split, Class root) {
|
private Object getInstance(String[] split, Class<?> root) {
|
||||||
try {
|
try {
|
||||||
Class<?> clazz = root == null ? MethodHandles.lookup().lookupClass() : root;
|
Class<?> clazz = root == null ? MethodHandles.lookup().lookupClass() : root;
|
||||||
Object instance = this;
|
Object instance = this;
|
||||||
while (split.length > 0) {
|
while (split.length > 0) {
|
||||||
switch (split.length) {
|
if (split.length == 1) {
|
||||||
case 1:
|
return instance;
|
||||||
return instance;
|
|
||||||
default:
|
|
||||||
Class found = null;
|
|
||||||
Class<?>[] classes = clazz.getDeclaredClasses();
|
|
||||||
for (Class current : classes) {
|
|
||||||
if (StringMan.isEqual(current.getSimpleName(), toFieldName(split[0]))) {
|
|
||||||
found = current;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Field instanceField = clazz.getDeclaredField(toFieldName(split[0]));
|
|
||||||
setAccessible(instanceField);
|
|
||||||
if (instanceField.getType() != ConfigBlock.class) {
|
|
||||||
Object value = instanceField.get(instance);
|
|
||||||
if (value == null) {
|
|
||||||
value = found.newInstance();
|
|
||||||
instanceField.set(instance, value);
|
|
||||||
}
|
|
||||||
clazz = found;
|
|
||||||
instance = value;
|
|
||||||
split = Arrays.copyOfRange(split, 1, split.length);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ConfigBlock value = (ConfigBlock) instanceField.get(instance);
|
|
||||||
if (value == null) {
|
|
||||||
value = new ConfigBlock();
|
|
||||||
instanceField.set(instance, value);
|
|
||||||
}
|
|
||||||
instance = value.get(split[1]);
|
|
||||||
if (instance == null) {
|
|
||||||
instance = found.newInstance();
|
|
||||||
value.put(split[1], instance);
|
|
||||||
}
|
|
||||||
clazz = found;
|
|
||||||
split = Arrays.copyOfRange(split, 2, split.length);
|
|
||||||
continue;
|
|
||||||
} catch (NoSuchFieldException ignored) {
|
|
||||||
}
|
|
||||||
if (found != null) {
|
|
||||||
split = Arrays.copyOfRange(split, 1, split.length);
|
|
||||||
clazz = found;
|
|
||||||
instance = clazz.newInstance();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
Class<?> found = null;
|
||||||
|
Class<?>[] classes = clazz.getDeclaredClasses();
|
||||||
|
for (Class<?> current : classes) {
|
||||||
|
if (StringMan.isEqual(current.getSimpleName(), toFieldName(split[0]))) {
|
||||||
|
found = current;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Field instanceField = clazz.getDeclaredField(toFieldName(split[0]));
|
||||||
|
setAccessible(instanceField);
|
||||||
|
if (instanceField.getType() != ConfigBlock.class) {
|
||||||
|
Object value = instanceField.get(instance);
|
||||||
|
if (value == null) {
|
||||||
|
value = found.getDeclaredConstructor().newInstance();
|
||||||
|
instanceField.set(instance, value);
|
||||||
|
}
|
||||||
|
clazz = found;
|
||||||
|
instance = value;
|
||||||
|
split = Arrays.copyOfRange(split, 1, split.length);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ConfigBlock value = (ConfigBlock) instanceField.get(instance);
|
||||||
|
if (value == null) {
|
||||||
|
value = new ConfigBlock();
|
||||||
|
instanceField.set(instance, value);
|
||||||
|
}
|
||||||
|
instance = value.get(split[1]);
|
||||||
|
if (instance == null) {
|
||||||
|
instance = found.getDeclaredConstructor().newInstance();
|
||||||
|
value.put(split[1], instance);
|
||||||
|
}
|
||||||
|
clazz = found;
|
||||||
|
split = Arrays.copyOfRange(split, 2, split.length);
|
||||||
|
continue;
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
if (found != null) {
|
||||||
|
split = Arrays.copyOfRange(split, 1, split.length);
|
||||||
|
clazz = found;
|
||||||
|
instance = clazz.getDeclaredConstructor().newInstance();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
@ -9,12 +9,28 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
|
|
||||||
public class DBHandler {
|
public class DBHandler {
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
/**
|
||||||
|
* @deprecated Use {@link #dbHandler()} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true, since = "2.0.0")
|
||||||
public static final DBHandler IMP = new DBHandler();
|
public static final DBHandler IMP = new DBHandler();
|
||||||
|
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||||
|
private static DBHandler INSTANCE;
|
||||||
private final Map<World, RollbackDatabase> databases = new ConcurrentHashMap<>(8, 0.9f, 1);
|
private final Map<World, RollbackDatabase> databases = new ConcurrentHashMap<>(8, 0.9f, 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an instance of the DBHandler.
|
||||||
|
*
|
||||||
|
* @return an instance of the DBHandler.
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
public static DBHandler dbHandler() {
|
||||||
|
if (INSTANCE == null) {
|
||||||
|
INSTANCE = new DBHandler();
|
||||||
|
}
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
public RollbackDatabase getDatabase(World world) {
|
public RollbackDatabase getDatabase(World world) {
|
||||||
RollbackDatabase database = databases.get(world);
|
RollbackDatabase database = databases.get(world);
|
||||||
if (database != null) {
|
if (database != null) {
|
||||||
|
Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren