mirror of
https://github.com/EngineHub/WorldEdit.git
synced 2024-12-15 04:41:37 +08:00
Clean up Gradle configuration
This commit is contained in:
parent
ada0a80faa
commit
28ca2e6b96
@ -3,26 +3,7 @@
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = "PaperMC"
|
||||
url = uri("https://repo.papermc.io/repository/maven-public/")
|
||||
content {
|
||||
includeGroupAndSubgroups("io.papermc")
|
||||
}
|
||||
}
|
||||
maven {
|
||||
name = "NeoForged Maven"
|
||||
url = uri("https://maven.neoforged.net/releases")
|
||||
content {
|
||||
includeGroupAndSubgroups("net.neoforged")
|
||||
}
|
||||
}
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
maven {
|
||||
name = "Fabric"
|
||||
url = uri("https://maven.fabricmc.net/")
|
||||
}
|
||||
maven {
|
||||
name = "EngineHub Repository"
|
||||
url = uri("https://maven.enginehub.org/repo/")
|
||||
@ -36,11 +17,8 @@
|
||||
implementation(libs.japicmp)
|
||||
implementation(libs.shadow)
|
||||
implementation(libs.jfrog.buildinfo)
|
||||
implementation(libs.neoGradle.userdev)
|
||||
implementation(libs.fabric.loom)
|
||||
implementation(libs.fabric.mixin)
|
||||
implementation(libs.codecov)
|
||||
implementation(libs.paperweight)
|
||||
implementation(libs.gson)
|
||||
constraints {
|
||||
val asmVersion = "[${libs.versions.minimumAsm.get()},)"
|
||||
implementation("org.ow2.asm:asm:$asmVersion") {
|
26
build-logic/src/main/kotlin/buildlogic.adapter.gradle.kts
Normal file
26
build-logic/src/main/kotlin/buildlogic.adapter.gradle.kts
Normal file
@ -0,0 +1,26 @@
|
||||
import buildlogic.stringyLibs
|
||||
import buildlogic.getVersion
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
id("buildlogic.common")
|
||||
id("buildlogic.common-java")
|
||||
id("io.papermc.paperweight.userdev")
|
||||
}
|
||||
|
||||
configure<buildlogic.CommonJavaExtension> {
|
||||
banSlf4j = false
|
||||
}
|
||||
|
||||
dependencies {
|
||||
"implementation"(project(":worldedit-bukkit"))
|
||||
constraints {
|
||||
"remapper"("net.fabricmc:tiny-remapper:[${stringyLibs.getVersion("minimumTinyRemapper")},)") {
|
||||
because("Need remapper to support Java 21")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("assemble") {
|
||||
dependsOn("reobfJar")
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.named
|
||||
import org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention
|
||||
import org.jfrog.gradle.plugin.artifactory.task.ArtifactoryTask
|
||||
|
||||
plugins {
|
||||
id("com.jfrog.artifactory")
|
||||
}
|
||||
|
||||
val ARTIFACTORY_CONTEXT_URL = "artifactory_contextUrl"
|
||||
val ARTIFACTORY_USER = "artifactory_user"
|
||||
val ARTIFACTORY_PASSWORD = "artifactory_password"
|
||||
|
||||
if (!project.hasProperty(ARTIFACTORY_CONTEXT_URL)) ext[ARTIFACTORY_CONTEXT_URL] = "http://localhost"
|
||||
if (!project.hasProperty(ARTIFACTORY_USER)) ext[ARTIFACTORY_USER] = "guest"
|
||||
if (!project.hasProperty(ARTIFACTORY_PASSWORD)) ext[ARTIFACTORY_PASSWORD] = ""
|
||||
|
||||
configure<ArtifactoryPluginConvention> {
|
||||
setContextUrl("${project.property(ARTIFACTORY_CONTEXT_URL)}")
|
||||
clientConfig.publisher.run {
|
||||
repoKey = when {
|
||||
"${project.version}".contains("SNAPSHOT") -> "libs-snapshot-local"
|
||||
else -> "libs-release-local"
|
||||
}
|
||||
username = "${project.property(ARTIFACTORY_USER)}"
|
||||
password = "${project.property(ARTIFACTORY_PASSWORD)}"
|
||||
isMaven = true
|
||||
isIvy = false
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named<ArtifactoryTask>("artifactoryPublish") {
|
||||
isSkip = true
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
plugins {
|
||||
id("com.jfrog.artifactory")
|
||||
}
|
||||
|
||||
// Artifactory eagerly evaluates publications, so this must run after all changes to artifacts are done
|
||||
afterEvaluate {
|
||||
tasks.named<org.jfrog.gradle.plugin.artifactory.task.ArtifactoryTask>("artifactoryPublish") {
|
||||
publications("maven")
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
import buildlogic.stringyLibs
|
||||
import buildlogic.getLibrary
|
||||
|
||||
plugins {
|
||||
id("eclipse")
|
||||
id("idea")
|
||||
id("checkstyle")
|
||||
id("buildlogic.common")
|
||||
}
|
||||
|
||||
val commonJava = extensions.create<buildlogic.CommonJavaExtension>("commonJava")
|
||||
commonJava.banSlf4j.convention(true)
|
||||
|
||||
tasks
|
||||
.withType<JavaCompile>()
|
||||
.matching { it.name == "compileJava" || it.name == "compileTestJava" }
|
||||
.configureEach {
|
||||
// TODO: re-enable this-escape when ANTLR suppresses it properly
|
||||
val disabledLint = listOf(
|
||||
"processing", "path", "fallthrough", "serial", "overloads", "this-escape",
|
||||
)
|
||||
options.release.set(21)
|
||||
options.compilerArgs.addAll(listOf("-Xlint:all") + disabledLint.map { "-Xlint:-$it" })
|
||||
options.isDeprecation = true
|
||||
options.encoding = "UTF-8"
|
||||
options.compilerArgs.add("-parameters")
|
||||
options.compilerArgs.add("-Werror")
|
||||
}
|
||||
|
||||
configure<CheckstyleExtension> {
|
||||
configFile = rootProject.file("config/checkstyle/checkstyle.xml")
|
||||
toolVersion = "9.1"
|
||||
}
|
||||
|
||||
tasks.withType<Test>().configureEach {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
"compileOnly"(stringyLibs.getLibrary("jsr305"))
|
||||
"testImplementation"(platform(stringyLibs.getLibrary("junit-bom")))
|
||||
"testImplementation"(stringyLibs.getLibrary("junit-jupiter-api"))
|
||||
"testImplementation"(stringyLibs.getLibrary("junit-jupiter-params"))
|
||||
"testImplementation"(platform(stringyLibs.getLibrary("mockito-bom")))
|
||||
"testImplementation"(stringyLibs.getLibrary("mockito-core"))
|
||||
"testImplementation"(stringyLibs.getLibrary("mockito-junit-jupiter"))
|
||||
"testRuntimeOnly"(stringyLibs.getLibrary("junit-jupiter-engine"))
|
||||
}
|
||||
|
||||
// Java 8 turns on doclint which we fail
|
||||
tasks.withType<Javadoc>().configureEach {
|
||||
options.encoding = "UTF-8"
|
||||
(options as StandardJavadocDocletOptions).apply {
|
||||
addBooleanOption("Werror", true)
|
||||
addBooleanOption("Xdoclint:all", true)
|
||||
addBooleanOption("Xdoclint:-missing", true)
|
||||
tags(
|
||||
"apiNote:a:API Note:",
|
||||
"implSpec:a:Implementation Requirements:",
|
||||
"implNote:a:Implementation Note:"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
configure<JavaPluginExtension> {
|
||||
withJavadocJar()
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
configurations["compileClasspath"].apply {
|
||||
resolutionStrategy.componentSelection {
|
||||
withModule("org.slf4j:slf4j-api") {
|
||||
if (commonJava.banSlf4j.get()) {
|
||||
reject("No SLF4J allowed on compile classpath")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("check").configure {
|
||||
dependsOn("checkstyleMain", "checkstyleTest")
|
||||
}
|
68
build-logic/src/main/kotlin/buildlogic.common.gradle.kts
Normal file
68
build-logic/src/main/kotlin/buildlogic.common.gradle.kts
Normal file
@ -0,0 +1,68 @@
|
||||
import buildlogic.getLibrary
|
||||
import buildlogic.stringyLibs
|
||||
import org.gradle.plugins.ide.idea.model.IdeaModel
|
||||
|
||||
plugins {
|
||||
id("org.cadixdev.licenser")
|
||||
}
|
||||
|
||||
group = rootProject.group
|
||||
version = rootProject.version
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = "EngineHub"
|
||||
url = uri("https://maven.enginehub.org/repo/")
|
||||
}
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
cacheChangingModulesFor(1, TimeUnit.DAYS)
|
||||
}
|
||||
}
|
||||
|
||||
plugins.withId("java") {
|
||||
the<JavaPluginExtension>().toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(21))
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
for (conf in listOf("implementation", "api")) {
|
||||
if (!configurations.names.contains(conf)) {
|
||||
continue
|
||||
}
|
||||
add(conf, platform(stringyLibs.getLibrary("log4j-bom")).map {
|
||||
val dep = create(it)
|
||||
dep.because("Mojang provides Log4j")
|
||||
dep
|
||||
})
|
||||
constraints {
|
||||
add(conf, stringyLibs.getLibrary("guava")) {
|
||||
because("Mojang provides Guava")
|
||||
}
|
||||
add(conf, stringyLibs.getLibrary("gson")) {
|
||||
because("Mojang provides Gson")
|
||||
}
|
||||
add(conf, stringyLibs.getLibrary("fastutil")) {
|
||||
because("Mojang provides FastUtil")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
license {
|
||||
header(rootProject.file("HEADER.txt"))
|
||||
include("**/*.java")
|
||||
include("**/*.kt")
|
||||
}
|
||||
|
||||
plugins.withId("idea") {
|
||||
configure<IdeaModel> {
|
||||
module {
|
||||
isDownloadSources = true
|
||||
isDownloadJavadoc = true
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
plugins {
|
||||
id("java")
|
||||
id("maven-publish")
|
||||
id("buildlogic.common-java")
|
||||
id("buildlogic.artifactory-sub")
|
||||
}
|
||||
|
||||
ext["internalVersion"] = "$version+${rootProject.ext["gitCommitHash"]}"
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
register<MavenPublication>("maven") {
|
||||
versionMapping {
|
||||
usage("java-api") {
|
||||
fromResolutionOf("runtimeClasspath")
|
||||
}
|
||||
usage("java-runtime") {
|
||||
fromResolutionResult()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
180
build-logic/src/main/kotlin/buildlogic.libs.gradle.kts
Normal file
180
build-logic/src/main/kotlin/buildlogic.libs.gradle.kts
Normal file
@ -0,0 +1,180 @@
|
||||
plugins {
|
||||
id("java-base")
|
||||
id("maven-publish")
|
||||
id("com.github.johnrengelman.shadow")
|
||||
id("com.jfrog.artifactory")
|
||||
id("buildlogic.common")
|
||||
id("buildlogic.artifactory-sub")
|
||||
}
|
||||
|
||||
// A horrible hack because `softwareComponentFactory` has to be gotten via plugin
|
||||
// gradle why
|
||||
internal open class LibsConfigPluginHack @Inject constructor(
|
||||
private val softwareComponentFactory: SoftwareComponentFactory
|
||||
) : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
val libsComponents = softwareComponentFactory.adhoc("libs")
|
||||
project.components.add(libsComponents)
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
create("shade")
|
||||
}
|
||||
|
||||
group = "${rootProject.group}.worldedit-libs"
|
||||
|
||||
val relocations = mapOf(
|
||||
"net.kyori.text" to "com.sk89q.worldedit.util.formatting.text",
|
||||
"net.kyori.minecraft" to "com.sk89q.worldedit.util.kyori",
|
||||
)
|
||||
|
||||
tasks.register<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("jar") {
|
||||
configurations = listOf(project.configurations["shade"])
|
||||
archiveClassifier.set("")
|
||||
|
||||
// Yeet module-info's
|
||||
exclude("module-info.class")
|
||||
|
||||
dependencies {
|
||||
exclude(dependency("com.google.guava:guava"))
|
||||
exclude(dependency("com.google.code.gson:gson"))
|
||||
exclude(dependency("com.google.errorprone:error_prone_annotations"))
|
||||
exclude(dependency("com.google.guava:failureaccess"))
|
||||
exclude(dependency("org.checkerframework:checker-qual"))
|
||||
exclude(dependency("org.jetbrains:annotations"))
|
||||
exclude(dependency("org.apache.logging.log4j:log4j-api"))
|
||||
exclude(dependency("com.google.code.findbugs:jsr305"))
|
||||
exclude {
|
||||
it.moduleGroup == "org.jetbrains.kotlin"
|
||||
}
|
||||
}
|
||||
|
||||
relocations.forEach { (from, to) ->
|
||||
relocate(from, to)
|
||||
}
|
||||
}
|
||||
val altConfigFiles = { artifactType: String ->
|
||||
val deps = configurations["shade"].incoming.dependencies
|
||||
.filterIsInstance<ModuleDependency>()
|
||||
.map { it.copy() }
|
||||
.map { dependency ->
|
||||
val category = dependency.attributes.getAttribute(Category.CATEGORY_ATTRIBUTE)?.name
|
||||
if (category == Category.REGULAR_PLATFORM || category == Category.ENFORCED_PLATFORM) {
|
||||
return@map dependency
|
||||
}
|
||||
try {
|
||||
dependency.artifact {
|
||||
name = dependency.name
|
||||
type = artifactType
|
||||
extension = "jar"
|
||||
classifier = artifactType
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
throw RuntimeException("Failed to add artifact to dependency: $dependency", e)
|
||||
}
|
||||
dependency
|
||||
}
|
||||
|
||||
files(configurations.detachedConfiguration(*deps.toTypedArray())
|
||||
.resolvedConfiguration.lenientConfiguration.artifacts
|
||||
.filter { it.classifier == artifactType }
|
||||
.map { zipTree(it.file) })
|
||||
}
|
||||
tasks.register<Jar>("sourcesJar") {
|
||||
from({
|
||||
altConfigFiles("sources")
|
||||
})
|
||||
|
||||
// Yeet module-info's
|
||||
exclude("module-info.java")
|
||||
|
||||
relocations.forEach { (from, to) ->
|
||||
val filePattern = Regex("(.*)${from.replace('.', '/')}((?:/|$).*)")
|
||||
val textPattern = Regex.fromLiteral(from)
|
||||
eachFile {
|
||||
filter {
|
||||
it.replaceFirst(textPattern, to)
|
||||
}
|
||||
path = path.replaceFirst(filePattern, "$1${to.replace('.', '/')}$2")
|
||||
}
|
||||
}
|
||||
archiveClassifier.set("sources")
|
||||
}
|
||||
|
||||
tasks.named("assemble").configure {
|
||||
dependsOn("jar", "sourcesJar")
|
||||
}
|
||||
|
||||
project.apply<LibsConfigPluginHack>()
|
||||
|
||||
val libsComponent = project.components["libs"] as AdhocComponentWithVariants
|
||||
|
||||
val apiElements = project.configurations.register("apiElements") {
|
||||
isVisible = false
|
||||
description = "API elements for libs"
|
||||
isCanBeResolved = false
|
||||
isCanBeConsumed = true
|
||||
attributes {
|
||||
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_API))
|
||||
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
|
||||
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
|
||||
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 16)
|
||||
}
|
||||
outgoing.artifact(tasks.named("jar"))
|
||||
}
|
||||
|
||||
val runtimeElements = project.configurations.register("runtimeElements") {
|
||||
isVisible = false
|
||||
description = "Runtime 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.LIBRARY))
|
||||
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
|
||||
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 16)
|
||||
}
|
||||
outgoing.artifact(tasks.named("jar"))
|
||||
}
|
||||
|
||||
val sourcesElements = project.configurations.register("sourcesElements") {
|
||||
isVisible = false
|
||||
description = "Source 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.SOURCES))
|
||||
}
|
||||
outgoing.artifact(tasks.named("sourcesJar"))
|
||||
}
|
||||
|
||||
libsComponent.addVariantsFromConfiguration(apiElements.get()) {
|
||||
mapToMavenScope("compile")
|
||||
}
|
||||
|
||||
libsComponent.addVariantsFromConfiguration(runtimeElements.get()) {
|
||||
mapToMavenScope("runtime")
|
||||
}
|
||||
|
||||
libsComponent.addVariantsFromConfiguration(sourcesElements.get()) {
|
||||
mapToMavenScope("runtime")
|
||||
}
|
||||
|
||||
configure<PublishingExtension> {
|
||||
publications {
|
||||
register<MavenPublication>("maven") {
|
||||
from(libsComponent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (project != project(":worldedit-libs:core")) {
|
||||
evaluationDependsOn(":worldedit-libs:core")
|
||||
configurations["shade"].shouldResolveConsistentlyWith(project(":worldedit-libs:core").configurations["shade"])
|
||||
}
|
53
build-logic/src/main/kotlin/buildlogic.platform.gradle.kts
Normal file
53
build-logic/src/main/kotlin/buildlogic.platform.gradle.kts
Normal file
@ -0,0 +1,53 @@
|
||||
plugins {
|
||||
id("com.github.johnrengelman.shadow")
|
||||
id("buildlogic.core-and-platform")
|
||||
}
|
||||
|
||||
val platform = extensions.create<buildlogic.PlatformExtension>("platform")
|
||||
platform.includeClasspath.convention(false)
|
||||
platform.extraAttributes.convention(mapOf())
|
||||
|
||||
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
|
||||
archiveClassifier.set("dist")
|
||||
dependencies {
|
||||
include(project(":worldedit-libs:core"))
|
||||
include(project(":worldedit-libs:${project.name.replace("worldedit-", "")}"))
|
||||
include(project(":worldedit-core"))
|
||||
exclude("com.google.code.findbugs:jsr305")
|
||||
}
|
||||
exclude("GradleStart**")
|
||||
exclude(".cache")
|
||||
exclude("LICENSE*")
|
||||
exclude("META-INF/maven/**")
|
||||
minimize()
|
||||
}
|
||||
val javaComponent = components["java"] as AdhocComponentWithVariants
|
||||
// I don't think we want this published (it's the shadow jar)
|
||||
javaComponent.withVariantsFromConfiguration(configurations["shadowRuntimeElements"]) {
|
||||
skip()
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
tasks.named<Jar>("jar") {
|
||||
val kind = platform.kind.get()
|
||||
val includeClasspath = platform.includeClasspath.get()
|
||||
val extraAttributes = platform.extraAttributes.get()
|
||||
|
||||
val version = project(":worldedit-core").version
|
||||
inputs.property("version", version)
|
||||
val attributes = mutableMapOf(
|
||||
"Implementation-Version" to version,
|
||||
"WorldEdit-Version" to version,
|
||||
"WorldEdit-Kind" to kind.name,
|
||||
"Main-Class" to kind.mainClass
|
||||
)
|
||||
if (includeClasspath) {
|
||||
attributes["Class-Path"] = listOf("truezip", "truevfs", "js")
|
||||
.map { "$it.jar" }
|
||||
.flatMap { listOf(it, "WorldEdit/$it") }
|
||||
.joinToString(separator = " ")
|
||||
}
|
||||
attributes.putAll(extraAttributes)
|
||||
manifest.attributes(attributes)
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package buildlogic
|
||||
|
||||
import org.gradle.api.provider.Property
|
||||
|
||||
interface CommonJavaExtension {
|
||||
val banSlf4j: Property<Boolean>
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
package buildlogic
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.MinimalExternalModuleDependency
|
||||
import org.gradle.api.artifacts.VersionCatalog
|
19
build-logic/src/main/kotlin/buildlogic/PlatformExtension.kt
Normal file
19
build-logic/src/main/kotlin/buildlogic/PlatformExtension.kt
Normal file
@ -0,0 +1,19 @@
|
||||
package buildlogic
|
||||
|
||||
import org.gradle.api.provider.MapProperty
|
||||
import org.gradle.api.provider.Property
|
||||
|
||||
interface PlatformExtension {
|
||||
val kind: Property<WorldEditKind>
|
||||
val includeClasspath: Property<Boolean>
|
||||
val extraAttributes: MapProperty<String, String>
|
||||
}
|
||||
|
||||
sealed class WorldEditKind(
|
||||
val name: String,
|
||||
val mainClass: String = "com.sk89q.worldedit.internal.util.InfoEntryPoint"
|
||||
) {
|
||||
class Standalone(mainClass: String) : WorldEditKind("STANDALONE", mainClass)
|
||||
object Mod : WorldEditKind("MOD")
|
||||
object Plugin : WorldEditKind("PLUGIN")
|
||||
}
|
@ -1,21 +1,25 @@
|
||||
import org.ajoberstar.grgit.Grgit
|
||||
|
||||
// needed for fabric to know where FF executor is....
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = "EngineHub"
|
||||
url = uri("https://maven.enginehub.org/repo/")
|
||||
}
|
||||
maven {
|
||||
name = "Fabric"
|
||||
url = uri("https://maven.fabricmc.net/")
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath(libs.fabric.loom)
|
||||
// needed for fabric to know where FF executor is....
|
||||
}
|
||||
}
|
||||
plugins {
|
||||
id("org.enginehub.codecov")
|
||||
alias(libs.plugins.codecov)
|
||||
jacoco
|
||||
id("buildlogic.common")
|
||||
id("buildlogic.artifactory-root")
|
||||
}
|
||||
|
||||
if (!project.hasProperty("gitCommitHash")) {
|
||||
@ -29,23 +33,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
logger.lifecycle("""
|
||||
*******************************************
|
||||
You are building WorldEdit!
|
||||
|
||||
If you encounter trouble:
|
||||
1) Read COMPILING.md if you haven't yet
|
||||
2) Try running 'build' in a separate Gradle run
|
||||
3) Use gradlew and not gradle
|
||||
4) If you still need help, ask on Discord! https://discord.gg/enginehub
|
||||
|
||||
Output files will be in [subproject]/build/libs
|
||||
*******************************************
|
||||
""")
|
||||
|
||||
applyCommonConfiguration()
|
||||
applyRootArtifactoryConfig()
|
||||
|
||||
val totalReport = tasks.register<JacocoReport>("jacocoTotalReport") {
|
||||
for (proj in subprojects) {
|
||||
proj.apply(plugin = "jacoco")
|
||||
|
@ -1,29 +0,0 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.dependencies
|
||||
|
||||
// For specific version pinning, see
|
||||
// https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/
|
||||
fun Project.applyPaperweightAdapterConfiguration(javaRelease: Int = 21) {
|
||||
applyCommonConfiguration()
|
||||
apply(plugin = "java-library")
|
||||
applyCommonJavaConfiguration(
|
||||
sourcesJar = true,
|
||||
javaRelease = javaRelease,
|
||||
banSlf4j = false,
|
||||
)
|
||||
apply(plugin = "io.papermc.paperweight.userdev")
|
||||
|
||||
dependencies {
|
||||
"implementation"(project(":worldedit-bukkit"))
|
||||
constraints {
|
||||
"remapper"("net.fabricmc:tiny-remapper:[${stringyLibs.getVersion("minimumTinyRemapper")},)") {
|
||||
because("Need remapper to support Java 21")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("assemble") {
|
||||
dependsOn("reobfJar")
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.named
|
||||
import org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention
|
||||
import org.jfrog.gradle.plugin.artifactory.task.ArtifactoryTask
|
||||
|
||||
private const val ARTIFACTORY_CONTEXT_URL = "artifactory_contextUrl"
|
||||
private const val ARTIFACTORY_USER = "artifactory_user"
|
||||
private const val ARTIFACTORY_PASSWORD = "artifactory_password"
|
||||
|
||||
fun Project.applyRootArtifactoryConfig() {
|
||||
if (!project.hasProperty(ARTIFACTORY_CONTEXT_URL)) ext[ARTIFACTORY_CONTEXT_URL] = "http://localhost"
|
||||
if (!project.hasProperty(ARTIFACTORY_USER)) ext[ARTIFACTORY_USER] = "guest"
|
||||
if (!project.hasProperty(ARTIFACTORY_PASSWORD)) ext[ARTIFACTORY_PASSWORD] = ""
|
||||
|
||||
apply(plugin = "com.jfrog.artifactory")
|
||||
configure<ArtifactoryPluginConvention> {
|
||||
setContextUrl("${project.property(ARTIFACTORY_CONTEXT_URL)}")
|
||||
clientConfig.publisher.run {
|
||||
repoKey = when {
|
||||
"${project.version}".contains("SNAPSHOT") -> "libs-snapshot-local"
|
||||
else -> "libs-release-local"
|
||||
}
|
||||
username = "${project.property(ARTIFACTORY_USER)}"
|
||||
password = "${project.property(ARTIFACTORY_PASSWORD)}"
|
||||
isMaven = true
|
||||
isIvy = false
|
||||
}
|
||||
}
|
||||
tasks.named<ArtifactoryTask>("artifactoryPublish") {
|
||||
isSkip = true
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.applyCommonArtifactoryConfig() {
|
||||
// Artifactory eagerly evaluates publications, so this must run after all changes to artifacts are done
|
||||
afterEvaluate {
|
||||
tasks.named<ArtifactoryTask>("artifactoryPublish") {
|
||||
publications("maven")
|
||||
}
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
import groovy.lang.Closure
|
||||
import org.cadixdev.gradle.licenser.LicenseExtension
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Dependency
|
||||
import org.gradle.api.artifacts.ExternalModuleDependency
|
||||
import org.gradle.api.plugins.JavaPluginExtension
|
||||
import org.gradle.jvm.toolchain.JavaLanguageVersion
|
||||
import org.gradle.kotlin.dsl.*
|
||||
import org.gradle.plugins.ide.idea.model.IdeaModel
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
fun Project.applyCommonConfiguration() {
|
||||
group = rootProject.group
|
||||
version = rootProject.version
|
||||
|
||||
repositories {
|
||||
mavenCentral {
|
||||
mavenContent {
|
||||
releasesOnly()
|
||||
}
|
||||
}
|
||||
maven { url = uri("https://maven.enginehub.org/repo/") }
|
||||
maven {
|
||||
url = uri("https://oss.sonatype.org/content/repositories/snapshots/")
|
||||
mavenContent {
|
||||
snapshotsOnly()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
cacheChangingModulesFor(1, TimeUnit.DAYS)
|
||||
}
|
||||
}
|
||||
|
||||
plugins.withId("java") {
|
||||
the<JavaPluginExtension>().toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(21))
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
for (conf in listOf("implementation", "api")) {
|
||||
if (!configurations.names.contains(conf)) {
|
||||
continue
|
||||
}
|
||||
add(conf, platform(stringyLibs.getLibrary("log4j-bom")).map {
|
||||
val dep = create(it)
|
||||
dep.because("Mojang provides Log4j")
|
||||
dep
|
||||
})
|
||||
constraints {
|
||||
add(conf, stringyLibs.getLibrary("guava")) {
|
||||
because("Mojang provides Guava")
|
||||
}
|
||||
add(conf, stringyLibs.getLibrary("gson")) {
|
||||
because("Mojang provides Gson")
|
||||
}
|
||||
add(conf, stringyLibs.getLibrary("fastutil")) {
|
||||
because("Mojang provides FastUtil")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply(plugin = "org.cadixdev.licenser")
|
||||
configure<LicenseExtension> {
|
||||
header(rootProject.file("HEADER.txt"))
|
||||
include("**/*.java")
|
||||
include("**/*.kt")
|
||||
}
|
||||
|
||||
plugins.withId("idea") {
|
||||
configure<IdeaModel> {
|
||||
module {
|
||||
isDownloadSources = true
|
||||
isDownloadJavadoc = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.JavaPluginExtension
|
||||
import org.gradle.api.plugins.quality.CheckstyleExtension
|
||||
import org.gradle.api.tasks.compile.JavaCompile
|
||||
import org.gradle.api.tasks.javadoc.Javadoc
|
||||
import org.gradle.api.tasks.testing.Test
|
||||
import org.gradle.external.javadoc.StandardJavadocDocletOptions
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.dependencies
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.withType
|
||||
|
||||
fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, javaRelease: Int = 17, banSlf4j: Boolean = true) {
|
||||
applyCommonConfiguration()
|
||||
apply(plugin = "eclipse")
|
||||
apply(plugin = "idea")
|
||||
apply(plugin = "checkstyle")
|
||||
|
||||
tasks
|
||||
.withType<JavaCompile>()
|
||||
.matching { it.name == "compileJava" || it.name == "compileTestJava" }
|
||||
.configureEach {
|
||||
// TODO: re-enable this-escape when ANTLR suppresses it properly
|
||||
val disabledLint = listOf(
|
||||
"processing", "path", "fallthrough", "serial", "overloads", "this-escape",
|
||||
)
|
||||
options.release.set(javaRelease)
|
||||
options.compilerArgs.addAll(listOf("-Xlint:all") + disabledLint.map { "-Xlint:-$it" })
|
||||
options.isDeprecation = true
|
||||
options.encoding = "UTF-8"
|
||||
options.compilerArgs.add("-parameters")
|
||||
options.compilerArgs.add("-Werror")
|
||||
}
|
||||
|
||||
configure<CheckstyleExtension> {
|
||||
configFile = rootProject.file("config/checkstyle/checkstyle.xml")
|
||||
toolVersion = "9.1"
|
||||
}
|
||||
|
||||
tasks.withType<Test>().configureEach {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
"compileOnly"(stringyLibs.getLibrary("jsr305"))
|
||||
"testImplementation"(platform(stringyLibs.getLibrary("junit-bom")))
|
||||
"testImplementation"(stringyLibs.getLibrary("junit-jupiter-api"))
|
||||
"testImplementation"(stringyLibs.getLibrary("junit-jupiter-params"))
|
||||
"testImplementation"(platform(stringyLibs.getLibrary("mockito-bom")))
|
||||
"testImplementation"(stringyLibs.getLibrary("mockito-core"))
|
||||
"testImplementation"(stringyLibs.getLibrary("mockito-junit-jupiter"))
|
||||
"testRuntimeOnly"(stringyLibs.getLibrary("junit-jupiter-engine"))
|
||||
}
|
||||
|
||||
// Java 8 turns on doclint which we fail
|
||||
tasks.withType<Javadoc>().configureEach {
|
||||
options.encoding = "UTF-8"
|
||||
(options as StandardJavadocDocletOptions).apply {
|
||||
addBooleanOption("Werror", true)
|
||||
addBooleanOption("Xdoclint:all", true)
|
||||
addBooleanOption("Xdoclint:-missing", true)
|
||||
tags(
|
||||
"apiNote:a:API Note:",
|
||||
"implSpec:a:Implementation Requirements:",
|
||||
"implNote:a:Implementation Note:"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
configure<JavaPluginExtension> {
|
||||
withJavadocJar()
|
||||
if (sourcesJar) {
|
||||
withSourcesJar()
|
||||
}
|
||||
}
|
||||
|
||||
if (banSlf4j) {
|
||||
configurations["compileClasspath"].apply {
|
||||
resolutionStrategy.componentSelection {
|
||||
withModule("org.slf4j:slf4j-api") {
|
||||
reject("No SLF4J allowed on compile classpath")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("check").configure {
|
||||
dependsOn("checkstyleMain", "checkstyleTest")
|
||||
}
|
||||
}
|
@ -1,214 +0,0 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.ExternalModuleDependency
|
||||
import org.gradle.api.artifacts.ModuleDependency
|
||||
import org.gradle.api.attributes.Bundling
|
||||
import org.gradle.api.attributes.Category
|
||||
import org.gradle.api.attributes.DocsType
|
||||
import org.gradle.api.attributes.LibraryElements
|
||||
import org.gradle.api.attributes.Usage
|
||||
import org.gradle.api.attributes.java.TargetJvmVersion
|
||||
import org.gradle.api.component.AdhocComponentWithVariants
|
||||
import org.gradle.api.component.SoftwareComponentFactory
|
||||
import org.gradle.api.publish.PublishingExtension
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.tasks.bundling.Jar
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.exclude
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.invoke
|
||||
import org.gradle.kotlin.dsl.named
|
||||
import org.gradle.kotlin.dsl.register
|
||||
import javax.inject.Inject
|
||||
|
||||
fun Project.applyLibrariesConfiguration() {
|
||||
applyCommonConfiguration()
|
||||
apply(plugin = "java-base")
|
||||
apply(plugin = "maven-publish")
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
apply(plugin = "com.jfrog.artifactory")
|
||||
|
||||
configurations {
|
||||
create("shade")
|
||||
}
|
||||
|
||||
group = "${rootProject.group}.worldedit-libs"
|
||||
|
||||
val relocations = mapOf(
|
||||
"net.kyori.text" to "com.sk89q.worldedit.util.formatting.text",
|
||||
"net.kyori.minecraft" to "com.sk89q.worldedit.util.kyori",
|
||||
)
|
||||
|
||||
tasks.register<ShadowJar>("jar") {
|
||||
configurations = listOf(project.configurations["shade"])
|
||||
archiveClassifier.set("")
|
||||
|
||||
// Yeet module-info's
|
||||
exclude("module-info.class")
|
||||
|
||||
dependencies {
|
||||
exclude(dependency("com.google.guava:guava"))
|
||||
exclude(dependency("com.google.code.gson:gson"))
|
||||
exclude(dependency("com.google.errorprone:error_prone_annotations"))
|
||||
exclude(dependency("com.google.guava:failureaccess"))
|
||||
exclude(dependency("org.checkerframework:checker-qual"))
|
||||
exclude(dependency("org.jetbrains:annotations"))
|
||||
exclude(dependency("org.apache.logging.log4j:log4j-api"))
|
||||
exclude(dependency("com.google.code.findbugs:jsr305"))
|
||||
exclude {
|
||||
it.moduleGroup == "org.jetbrains.kotlin"
|
||||
}
|
||||
}
|
||||
|
||||
relocations.forEach { (from, to) ->
|
||||
relocate(from, to)
|
||||
}
|
||||
}
|
||||
val altConfigFiles = { artifactType: String ->
|
||||
val deps = configurations["shade"].incoming.dependencies
|
||||
.filterIsInstance<ModuleDependency>()
|
||||
.map { it.copy() }
|
||||
.map { dependency ->
|
||||
val category = dependency.attributes.getAttribute(Category.CATEGORY_ATTRIBUTE)?.name
|
||||
if (category == Category.REGULAR_PLATFORM || category == Category.ENFORCED_PLATFORM) {
|
||||
return@map dependency
|
||||
}
|
||||
try {
|
||||
dependency.artifact {
|
||||
name = dependency.name
|
||||
type = artifactType
|
||||
extension = "jar"
|
||||
classifier = artifactType
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
throw RuntimeException("Failed to add artifact to dependency: $dependency", e)
|
||||
}
|
||||
dependency
|
||||
}
|
||||
|
||||
files(configurations.detachedConfiguration(*deps.toTypedArray())
|
||||
.resolvedConfiguration.lenientConfiguration.artifacts
|
||||
.filter { it.classifier == artifactType }
|
||||
.map { zipTree(it.file) })
|
||||
}
|
||||
tasks.register<Jar>("sourcesJar") {
|
||||
from({
|
||||
altConfigFiles("sources")
|
||||
})
|
||||
|
||||
// Yeet module-info's
|
||||
exclude("module-info.java")
|
||||
|
||||
relocations.forEach { (from, to) ->
|
||||
val filePattern = Regex("(.*)${from.replace('.', '/')}((?:/|$).*)")
|
||||
val textPattern = Regex.fromLiteral(from)
|
||||
eachFile {
|
||||
filter {
|
||||
it.replaceFirst(textPattern, to)
|
||||
}
|
||||
path = path.replaceFirst(filePattern, "$1${to.replace('.', '/')}$2")
|
||||
}
|
||||
}
|
||||
archiveClassifier.set("sources")
|
||||
}
|
||||
|
||||
tasks.named("assemble").configure {
|
||||
dependsOn("jar", "sourcesJar")
|
||||
}
|
||||
|
||||
project.apply<LibsConfigPluginHack>()
|
||||
|
||||
val libsComponent = project.components["libs"] as AdhocComponentWithVariants
|
||||
|
||||
val apiElements = project.configurations.register("apiElements") {
|
||||
isVisible = false
|
||||
description = "API elements for libs"
|
||||
isCanBeResolved = false
|
||||
isCanBeConsumed = true
|
||||
attributes {
|
||||
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_API))
|
||||
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
|
||||
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
|
||||
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 16)
|
||||
}
|
||||
outgoing.artifact(tasks.named("jar"))
|
||||
}
|
||||
|
||||
val runtimeElements = project.configurations.register("runtimeElements") {
|
||||
isVisible = false
|
||||
description = "Runtime 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.LIBRARY))
|
||||
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
|
||||
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 16)
|
||||
}
|
||||
outgoing.artifact(tasks.named("jar"))
|
||||
}
|
||||
|
||||
val sourcesElements = project.configurations.register("sourcesElements") {
|
||||
isVisible = false
|
||||
description = "Source 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.SOURCES))
|
||||
}
|
||||
outgoing.artifact(tasks.named("sourcesJar"))
|
||||
}
|
||||
|
||||
libsComponent.addVariantsFromConfiguration(apiElements.get()) {
|
||||
mapToMavenScope("compile")
|
||||
}
|
||||
|
||||
libsComponent.addVariantsFromConfiguration(runtimeElements.get()) {
|
||||
mapToMavenScope("runtime")
|
||||
}
|
||||
|
||||
libsComponent.addVariantsFromConfiguration(sourcesElements.get()) {
|
||||
mapToMavenScope("runtime")
|
||||
}
|
||||
|
||||
configure<PublishingExtension> {
|
||||
publications {
|
||||
register<MavenPublication>("maven") {
|
||||
from(libsComponent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
applyCommonArtifactoryConfig()
|
||||
}
|
||||
|
||||
// A horrible hack because `softwareComponentFactory` has to be gotten via plugin
|
||||
// gradle why
|
||||
internal open class LibsConfigPluginHack @Inject constructor(
|
||||
private val softwareComponentFactory: SoftwareComponentFactory
|
||||
) : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
val libsComponents = softwareComponentFactory.adhoc("libs")
|
||||
project.components.add(libsComponents)
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.constrainDependenciesToLibsCore() {
|
||||
evaluationDependsOn(":worldedit-libs:core")
|
||||
val coreDeps = project(":worldedit-libs:core").configurations["shade"].dependencies
|
||||
.filterIsInstance<ExternalModuleDependency>()
|
||||
dependencies.constraints {
|
||||
for (coreDep in coreDeps) {
|
||||
add("shade", "${coreDep.group}:${coreDep.name}:${coreDep.version}") {
|
||||
because("libs should align with libs:core")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.component.AdhocComponentWithVariants
|
||||
import org.gradle.api.publish.PublishingExtension
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.tasks.bundling.Jar
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.named
|
||||
import org.gradle.kotlin.dsl.register
|
||||
import kotlin.collections.set
|
||||
|
||||
fun Project.applyPlatformAndCoreConfiguration(javaRelease: Int = 21) {
|
||||
applyCommonConfiguration()
|
||||
apply(plugin = "java")
|
||||
apply(plugin = "maven-publish")
|
||||
apply(plugin = "com.jfrog.artifactory")
|
||||
applyCommonJavaConfiguration(
|
||||
sourcesJar = name in setOf("worldedit-core", "worldedit-bukkit", "worldedit-fabric"),
|
||||
javaRelease = javaRelease,
|
||||
banSlf4j = name !in setOf("worldedit-fabric", "worldedit-neoforge", "worldedit-sponge"),
|
||||
)
|
||||
|
||||
ext["internalVersion"] = "$version+${rootProject.ext["gitCommitHash"]}"
|
||||
|
||||
configure<PublishingExtension> {
|
||||
publications {
|
||||
register<MavenPublication>("maven") {
|
||||
versionMapping {
|
||||
usage("java-api") {
|
||||
fromResolutionOf("runtimeClasspath")
|
||||
}
|
||||
usage("java-runtime") {
|
||||
fromResolutionResult()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
applyCommonArtifactoryConfig()
|
||||
}
|
||||
|
||||
fun Project.applyShadowConfiguration() {
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
archiveClassifier.set("dist")
|
||||
dependencies {
|
||||
include(project(":worldedit-libs:core"))
|
||||
include(project(":worldedit-libs:${project.name.replace("worldedit-", "")}"))
|
||||
include(project(":worldedit-core"))
|
||||
exclude("com.google.code.findbugs:jsr305")
|
||||
}
|
||||
exclude("GradleStart**")
|
||||
exclude(".cache")
|
||||
exclude("LICENSE*")
|
||||
exclude("META-INF/maven/**")
|
||||
minimize()
|
||||
}
|
||||
val javaComponent = components["java"] as AdhocComponentWithVariants
|
||||
// I don't think we want this published (it's the shadow jar)
|
||||
javaComponent.withVariantsFromConfiguration(configurations["shadowRuntimeElements"]) {
|
||||
skip()
|
||||
}
|
||||
}
|
||||
|
||||
private val CLASSPATH = listOf("truezip", "truevfs", "js")
|
||||
.map { "$it.jar" }
|
||||
.flatMap { listOf(it, "WorldEdit/$it") }
|
||||
.joinToString(separator = " ")
|
||||
|
||||
sealed class WorldEditKind(
|
||||
val name: String,
|
||||
val mainClass: String = "com.sk89q.worldedit.internal.util.InfoEntryPoint"
|
||||
) {
|
||||
class Standalone(mainClass: String) : WorldEditKind("STANDALONE", mainClass)
|
||||
object Mod : WorldEditKind("MOD")
|
||||
object Plugin : WorldEditKind("PLUGIN")
|
||||
}
|
||||
|
||||
fun Project.addJarManifest(kind: WorldEditKind, includeClasspath: Boolean = false, extraAttributes: Map<String, String> = mapOf()) {
|
||||
tasks.named<Jar>("jar") {
|
||||
val version = project(":worldedit-core").version
|
||||
inputs.property("version", version)
|
||||
val attributes = mutableMapOf(
|
||||
"Implementation-Version" to version,
|
||||
"WorldEdit-Version" to version,
|
||||
"WorldEdit-Kind" to kind.name,
|
||||
"Main-Class" to kind.mainClass
|
||||
)
|
||||
if (includeClasspath) {
|
||||
attributes["Class-Path"] = CLASSPATH
|
||||
}
|
||||
attributes.putAll(extraAttributes)
|
||||
manifest.attributes(attributes)
|
||||
}
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
[versions]
|
||||
neoGradle = "7.0.107"
|
||||
[plugins]
|
||||
codecov = "org.enginehub.codecov:0.2.0"
|
||||
neogradle-userdev = "net.neoforged.gradle.userdev:7.0.107"
|
||||
fabric-loom = "fabric-loom:1.6.9"
|
||||
|
||||
[versions]
|
||||
kyoriText = "3.0.4"
|
||||
piston = "0.5.10"
|
||||
autoValue = "1.10.4"
|
||||
@ -29,10 +32,8 @@ japicmp = "me.champeau.gradle:japicmp-gradle-plugin:0.4.2"
|
||||
shadow = "com.github.johnrengelman:shadow:8.1.1"
|
||||
jfrog-buildinfo = "org.jfrog.buildinfo:build-info-extractor-gradle:5.2.0"
|
||||
|
||||
fabric-loom = "net.fabricmc:fabric-loom:1.6.9"
|
||||
fabric-mixin = "net.fabricmc:sponge-mixin:0.13.3+mixin.0.8.5"
|
||||
|
||||
codecov = "org.enginehub.gradle:gradle-codecov-plugin:0.2.0"
|
||||
paperweight = "io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.6.0"
|
||||
|
||||
linBus-bom = "org.enginehub.lin-bus:lin-bus-bom:0.1.0-SNAPSHOT"
|
||||
@ -89,10 +90,6 @@ fastutil = "it.unimi.dsi:fastutil:8.5.12!!"
|
||||
# may not be the same as the ones in the latest Bukkit API.
|
||||
snakeyaml = "org.yaml:snakeyaml:2.0"
|
||||
|
||||
[libraries.neoGradle-userdev]
|
||||
module = "net.neoforged.gradle:userdev"
|
||||
version.ref = "neoGradle"
|
||||
|
||||
[libraries.kyoriText-api]
|
||||
module = "net.kyori:text-api"
|
||||
version.ref = "kyoriText"
|
||||
|
@ -1,10 +1,9 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
maven {
|
||||
name = "Fabric"
|
||||
url = uri("https://maven.fabricmc.net/")
|
||||
name = "EngineHub"
|
||||
url = uri("https://maven.enginehub.org/repo/")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12,8 +11,24 @@
|
||||
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
|
||||
}
|
||||
|
||||
logger.lifecycle("""
|
||||
*******************************************
|
||||
You are building WorldEdit!
|
||||
|
||||
If you encounter trouble:
|
||||
1) Read COMPILING.md if you haven't yet
|
||||
2) Try running 'build' in a separate Gradle run
|
||||
3) Use gradlew and not gradle
|
||||
4) If you still need help, ask on Discord! https://discord.gg/enginehub
|
||||
|
||||
Output files will be in [subproject]/build/libs
|
||||
*******************************************
|
||||
""")
|
||||
|
||||
rootProject.name = "worldedit"
|
||||
|
||||
includeBuild("build-logic")
|
||||
|
||||
include("worldedit-libs")
|
||||
|
||||
listOf("1.19.4", "1.20", "1.20.2", "1.20.4", "1.20.5").forEach {
|
||||
|
@ -74,6 +74,19 @@
|
||||
(this as? ModuleDependency)?.isTransitive = false
|
||||
}
|
||||
)
|
||||
val resolvedOldJar = files({
|
||||
try {
|
||||
conf.resolvedConfiguration.rethrowFailure()
|
||||
conf
|
||||
} catch (e: ResolveException) {
|
||||
if (e.cause is ModuleVersionNotFoundException) {
|
||||
logger.warn("Skipping check for $projectFragment API compatibility because there is no jar to compare against")
|
||||
setOf<File>()
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
})
|
||||
val checkApi = tasks.register<JapicmpTask>("check${capitalizedFragment}ApiCompatibility") {
|
||||
group = "API Compatibility"
|
||||
description = "Check API compatibility for $capitalizedFragment API"
|
||||
@ -89,20 +102,10 @@
|
||||
|
||||
onlyIf {
|
||||
// Only check if we have a jar to compare against
|
||||
try {
|
||||
conf.resolvedConfiguration.rethrowFailure()
|
||||
true
|
||||
} catch (e: ResolveException) {
|
||||
if (e.cause is ModuleVersionNotFoundException) {
|
||||
it.logger.warn("Skipping check for $projectFragment API compatibility because there is no jar to compare against")
|
||||
false
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
!resolvedOldJar.isEmpty
|
||||
}
|
||||
|
||||
oldClasspath.from(conf)
|
||||
oldClasspath.from(resolvedOldJar)
|
||||
newClasspath.from(proj.tasks.named("jar"))
|
||||
onlyModified.set(false)
|
||||
failOnModification.set(false) // report does the failing (so we can accept)
|
||||
|
@ -1,8 +0,0 @@
|
||||
import io.papermc.paperweight.userdev.PaperweightUserDependenciesExtension
|
||||
|
||||
applyPaperweightAdapterConfiguration()
|
||||
|
||||
dependencies {
|
||||
// https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/
|
||||
the<PaperweightUserDependenciesExtension>().paperDevBundle("1.18.2-R0.1-20220920.010157-167")
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,98 +0,0 @@
|
||||
/*
|
||||
* 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.impl.v1_18_R2;
|
||||
|
||||
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) {
|
||||
}
|
||||
}
|
@ -1,189 +0,0 @@
|
||||
/*
|
||||
* 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.impl.v1_18_R2;
|
||||
|
||||
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.world.block.BlockState;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData;
|
||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||
import org.enginehub.linbus.tree.LinCompoundTag;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Objects;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class PaperweightWorldNativeAccess implements WorldNativeAccess<LevelChunk, net.minecraft.world.level.block.state.BlockState, BlockPos> {
|
||||
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(BlockPos position, LinCompoundTag tag) {
|
||||
// We will assume that the tile entity was created for us
|
||||
BlockEntity tileEntity = getWorld().getBlockEntity(position);
|
||||
if (tileEntity == null) {
|
||||
return false;
|
||||
}
|
||||
Tag nativeTag = adapter.fromNative(tag);
|
||||
PaperweightAdapter.readTagIntoTileEntity((CompoundTag) nativeTag, tileEntity);
|
||||
return true;
|
||||
}
|
||||
|
||||
@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());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBlock(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) {
|
||||
ServerLevel world = getWorld();
|
||||
newState.onPlace(world, pos, oldState, false);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
import io.papermc.paperweight.userdev.PaperweightUserDependenciesExtension
|
||||
|
||||
applyPaperweightAdapterConfiguration()
|
||||
plugins {
|
||||
id("buildlogic.adapter")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/
|
||||
|
@ -1,6 +1,8 @@
|
||||
import io.papermc.paperweight.userdev.PaperweightUserDependenciesExtension
|
||||
|
||||
applyPaperweightAdapterConfiguration()
|
||||
plugins {
|
||||
id("buildlogic.adapter")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/
|
||||
|
@ -1,6 +1,8 @@
|
||||
import io.papermc.paperweight.userdev.PaperweightUserDependenciesExtension
|
||||
|
||||
applyPaperweightAdapterConfiguration()
|
||||
plugins {
|
||||
id("buildlogic.adapter")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/
|
||||
|
@ -1,6 +1,8 @@
|
||||
import io.papermc.paperweight.userdev.PaperweightUserDependenciesExtension
|
||||
|
||||
applyPaperweightAdapterConfiguration()
|
||||
plugins {
|
||||
id("buildlogic.adapter")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/
|
||||
|
@ -1,6 +1,8 @@
|
||||
import io.papermc.paperweight.userdev.PaperweightUserDependenciesExtension
|
||||
|
||||
applyPaperweightAdapterConfiguration()
|
||||
plugins {
|
||||
id("buildlogic.adapter")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/
|
||||
|
@ -3,14 +3,19 @@
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
id("buildlogic.platform")
|
||||
}
|
||||
|
||||
applyPlatformAndCoreConfiguration()
|
||||
applyShadowConfiguration()
|
||||
platform {
|
||||
kind = buildlogic.WorldEditKind.Plugin
|
||||
includeClasspath = true
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven { url = uri("https://hub.spigotmc.org/nexus/content/groups/public") }
|
||||
maven { url = uri("https://repo.papermc.io/repository/maven-public/") }
|
||||
maven {
|
||||
name = "Spigot"
|
||||
url = uri("https://hub.spigotmc.org/nexus/content/groups/public")
|
||||
}
|
||||
}
|
||||
|
||||
val localImplementation = configurations.create("localImplementation") {
|
||||
@ -79,8 +84,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
addJarManifest(WorldEditKind.Plugin, includeClasspath = true)
|
||||
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
configurations.add(adapters)
|
||||
dependencies {
|
||||
|
@ -2,17 +2,16 @@
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
id("buildlogic.platform")
|
||||
}
|
||||
|
||||
applyPlatformAndCoreConfiguration()
|
||||
applyShadowConfiguration()
|
||||
addJarManifest(
|
||||
WorldEditKind.Standalone("com.sk89q.worldedit.cli.CLIWorldEdit"),
|
||||
platform {
|
||||
kind = buildlogic.WorldEditKind.Standalone("com.sk89q.worldedit.cli.CLIWorldEdit")
|
||||
extraAttributes = mapOf(
|
||||
// We don't have any multi-release stuff, but Log4J does.
|
||||
"Multi-Release" to "true",
|
||||
),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
"compileOnly"(project(":worldedit-libs:core:ap"))
|
||||
|
@ -4,10 +4,9 @@
|
||||
plugins {
|
||||
`java-library`
|
||||
antlr
|
||||
id("buildlogic.core-and-platform")
|
||||
}
|
||||
|
||||
applyPlatformAndCoreConfiguration()
|
||||
|
||||
repositories {
|
||||
ivy {
|
||||
url = uri("https://repo.enginehub.org/language-files/")
|
||||
|
@ -1,10 +1,9 @@
|
||||
plugins {
|
||||
kotlin("jvm") version "1.9.23"
|
||||
application
|
||||
id("buildlogic.common")
|
||||
}
|
||||
|
||||
applyCommonConfiguration()
|
||||
|
||||
application.mainClass.set("com.sk89q.worldedit.internal.util.DocumentationPrinter")
|
||||
tasks.named<JavaExec>("run") {
|
||||
workingDir = rootProject.projectDir
|
||||
|
@ -5,12 +5,20 @@
|
||||
import net.fabricmc.loom.task.RunGameTask
|
||||
|
||||
plugins {
|
||||
id("fabric-loom")
|
||||
alias(libs.plugins.fabric.loom)
|
||||
`java-library`
|
||||
id("buildlogic.platform")
|
||||
}
|
||||
|
||||
applyPlatformAndCoreConfiguration()
|
||||
applyShadowConfiguration()
|
||||
commonJava {
|
||||
// Not easy to do, because it's in a bunch of separate configurations
|
||||
banSlf4j = false
|
||||
}
|
||||
|
||||
platform {
|
||||
kind = buildlogic.WorldEditKind.Mod
|
||||
includeClasspath = true
|
||||
}
|
||||
|
||||
val fabricApiConfiguration: Configuration = configurations.create("fabricApi")
|
||||
|
||||
@ -24,12 +32,12 @@
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = "Fabric"
|
||||
url = uri("https://maven.fabricmc.net/")
|
||||
name = "EngineHub"
|
||||
url = uri("https://maven.enginehub.org/repo/")
|
||||
}
|
||||
getByName("Mojang") {
|
||||
content {
|
||||
includeGroupByRegex("com\\.mojang\\..*")
|
||||
includeGroupAndSubgroups("com.mojang")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -60,11 +68,6 @@
|
||||
// No need for this at runtime
|
||||
"modCompileOnly"(libs.fabric.permissions.api)
|
||||
|
||||
// Hook these up manually, because Fabric doesn't seem to quite do it properly.
|
||||
"compileOnly"(libs.fabric.mixin)
|
||||
"annotationProcessor"(libs.fabric.mixin)
|
||||
"annotationProcessor"(libs.fabric.loom)
|
||||
|
||||
// Silence some warnings, since apparently this isn't on the compile classpath like it should be.
|
||||
"compileOnly"(libs.errorprone.annotations)
|
||||
}
|
||||
@ -88,8 +91,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
addJarManifest(WorldEditKind.Mod, includeClasspath = true)
|
||||
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
archiveClassifier.set("dist-dev")
|
||||
dependencies {
|
||||
|
@ -1,11 +1,5 @@
|
||||
applyLibrariesConfiguration()
|
||||
constrainDependenciesToLibsCore()
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = "SpigotMC"
|
||||
url = uri("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
|
||||
}
|
||||
plugins {
|
||||
id("buildlogic.libs")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
@ -1 +1,3 @@
|
||||
applyLibrariesConfiguration()
|
||||
plugins {
|
||||
id("buildlogic.libs")
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
applyLibrariesConfiguration()
|
||||
plugins {
|
||||
id("buildlogic.libs")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// These are here because they use net.kyori:text-api -- so they need to be relocated too
|
||||
|
@ -1,4 +1,6 @@
|
||||
applyLibrariesConfiguration()
|
||||
plugins {
|
||||
id("buildlogic.libs")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
"shade"(libs.kyoriText.api)
|
||||
|
@ -1 +1,3 @@
|
||||
applyLibrariesConfiguration()
|
||||
plugins {
|
||||
id("buildlogic.libs")
|
||||
}
|
||||
|
@ -1 +1,3 @@
|
||||
applyLibrariesConfiguration()
|
||||
plugins {
|
||||
id("buildlogic.libs")
|
||||
}
|
||||
|
@ -1,11 +0,0 @@
|
||||
applyLibrariesConfiguration()
|
||||
constrainDependenciesToLibsCore()
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = "Sponge"
|
||||
url = uri("https://repo.spongepowered.org/maven")
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
}
|
@ -4,10 +4,10 @@
|
||||
|
||||
plugins {
|
||||
base
|
||||
id("buildlogic.common")
|
||||
alias(libs.plugins.fabric.loom) apply false
|
||||
}
|
||||
|
||||
applyCommonConfiguration()
|
||||
|
||||
open class MergeManifests : DefaultTask() {
|
||||
@InputFiles
|
||||
val inputManifests: ConfigurableFileCollection = project.objects.fileCollection()
|
||||
|
@ -2,12 +2,19 @@
|
||||
import net.neoforged.gradle.dsl.common.runs.run.Run
|
||||
|
||||
plugins {
|
||||
id("net.neoforged.gradle.userdev")
|
||||
alias(libs.plugins.neogradle.userdev)
|
||||
`java-library`
|
||||
id("buildlogic.platform")
|
||||
}
|
||||
|
||||
applyPlatformAndCoreConfiguration()
|
||||
applyShadowConfiguration()
|
||||
commonJava {
|
||||
// Not easy to do, because it's in a bunch of separate configurations
|
||||
banSlf4j = false
|
||||
}
|
||||
|
||||
platform {
|
||||
kind = buildlogic.WorldEditKind.Mod
|
||||
}
|
||||
|
||||
val minecraftVersion = libs.versions.neoforge.minecraft.get()
|
||||
val nextMajorMinecraftVersion: String = minecraftVersion.split('.').let { (useless, major) ->
|
||||
@ -20,20 +27,16 @@
|
||||
}
|
||||
|
||||
repositories {
|
||||
val toRemove = mutableListOf<MavenArtifactRepository>()
|
||||
for (repo in project.repositories) {
|
||||
if (repo is MavenArtifactRepository && repo.url.toString() == "https://maven.neoforged.net/releases/") {
|
||||
repo.mavenContent {
|
||||
includeGroupAndSubgroups("net.neoforged")
|
||||
}
|
||||
toRemove.add(repo)
|
||||
}
|
||||
}
|
||||
// For Fabric's mixin fork
|
||||
toRemove.forEach { remove(it) }
|
||||
maven {
|
||||
name = "Fabric"
|
||||
url = uri("https://maven.fabricmc.net/")
|
||||
mavenContent {
|
||||
includeGroup("net.fabricmc")
|
||||
}
|
||||
name = "EngineHub"
|
||||
url = uri("https://maven.enginehub.org/repo/")
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,8 +109,6 @@
|
||||
from(project(":worldedit-core").tasks.named("processResources"))
|
||||
}
|
||||
|
||||
addJarManifest(WorldEditKind.Mod, includeClasspath = false)
|
||||
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
dependencies {
|
||||
relocate("org.antlr.v4", "com.sk89q.worldedit.antlr4")
|
||||
|
@ -1,81 +0,0 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.spongepowered.gradle.plugin.config.PluginLoaders
|
||||
import org.spongepowered.plugin.metadata.model.PluginDependency
|
||||
|
||||
plugins {
|
||||
id("org.spongepowered.gradle.plugin")
|
||||
id("org.spongepowered.gradle.vanilla")
|
||||
}
|
||||
|
||||
applyPlatformAndCoreConfiguration()
|
||||
applyShadowConfiguration()
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
minecraft {
|
||||
version("1.20")
|
||||
}
|
||||
|
||||
val spongeApiVersion = "11.0.0-SNAPSHOT";
|
||||
|
||||
sponge {
|
||||
apiVersion(spongeApiVersion)
|
||||
license("GPL-3.0-or-later")
|
||||
plugin("worldedit") {
|
||||
loader {
|
||||
name(PluginLoaders.JAVA_PLAIN)
|
||||
version("1.0")
|
||||
}
|
||||
displayName("WorldEdit")
|
||||
version(project.ext["internalVersion"].toString())
|
||||
entrypoint("com.sk89q.worldedit.sponge.SpongeWorldEdit")
|
||||
description("WorldEdit is an easy-to-use in-game world editor for Minecraft, supporting both single- and multi-player.")
|
||||
links {
|
||||
homepage("https://enginehub.org/worldedit/")
|
||||
source("https://github.com/EngineHub/WorldEdit")
|
||||
issues("https://github.com/EngineHub/WorldEdit/issues")
|
||||
}
|
||||
contributor("EngineHub") {
|
||||
description("Various members of the EngineHub team")
|
||||
}
|
||||
dependency("spongeapi") {
|
||||
loadOrder(PluginDependency.LoadOrder.AFTER)
|
||||
optional(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":worldedit-core"))
|
||||
api(project(":worldedit-libs:sponge"))
|
||||
|
||||
api("org.apache.logging.log4j:log4j-api")
|
||||
implementation("org.bstats:bstats-sponge:3.0.0")
|
||||
implementation("it.unimi.dsi:fastutil")
|
||||
|
||||
// Silence some warnings, since apparently this isn't on the compile classpath like it should be.
|
||||
compileOnly("com.google.errorprone:error_prone_annotations:2.11.0")
|
||||
}
|
||||
|
||||
configure<BasePluginExtension> {
|
||||
archivesName.set("${project.name}-api$spongeApiVersion")
|
||||
}
|
||||
|
||||
addJarManifest(WorldEditKind.Mod, includeClasspath = true)
|
||||
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
dependencies {
|
||||
include(dependency("org.bstats:"))
|
||||
include(dependency("org.antlr:antlr4-runtime"))
|
||||
include(dependency("com.sk89q.lib:jlibnoise"))
|
||||
|
||||
relocate("org.antlr.v4", "com.sk89q.worldedit.antlr4")
|
||||
relocate("org.bstats", "com.sk89q.worldedit.sponge.bstats")
|
||||
relocate("net.royawesome.jlibnoise", "com.sk89q.worldedit.jlibnoise")
|
||||
}
|
||||
}
|
||||
tasks.named("assemble").configure {
|
||||
dependsOn("shadowJar")
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.util.lifecycle.SimpleLifecycled;
|
||||
import org.spongepowered.api.ResourceKey;
|
||||
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
|
||||
import org.spongepowered.api.event.Listener;
|
||||
import org.spongepowered.api.event.lifecycle.RegisterChannelEvent;
|
||||
import org.spongepowered.api.network.ServerPlayerConnection;
|
||||
import org.spongepowered.api.network.channel.ChannelBuf;
|
||||
import org.spongepowered.api.network.channel.raw.RawDataChannel;
|
||||
import org.spongepowered.api.network.channel.raw.play.RawPlayDataHandler;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class CUIChannelHandler implements RawPlayDataHandler<ServerPlayerConnection> {
|
||||
public static final ResourceKey CUI_PLUGIN_CHANNEL = ResourceKey.of("worldedit", "cui");
|
||||
private static final SimpleLifecycled<RawDataChannel> CHANNEL = SimpleLifecycled.invalid();
|
||||
|
||||
public static final class RegistrationHandler {
|
||||
@Listener
|
||||
public void onChannelRegistration(RegisterChannelEvent event) {
|
||||
RawDataChannel channel = event.register(CUI_PLUGIN_CHANNEL, RawDataChannel.class);
|
||||
channel.play().addHandler(ServerPlayerConnection.class, new CUIChannelHandler());
|
||||
CHANNEL.newValue(channel);
|
||||
}
|
||||
}
|
||||
|
||||
public static RawDataChannel channel() {
|
||||
return CHANNEL.valueOrThrow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePayload(ChannelBuf data, ServerPlayerConnection connection) {
|
||||
ServerPlayer player = connection.player();
|
||||
|
||||
SpongePlayer spongePlayer = SpongeAdapter.adapt(player);
|
||||
LocalSession session = WorldEdit.getInstance().getSessionManager().get(
|
||||
spongePlayer
|
||||
);
|
||||
|
||||
session.handleCUIInitializationMessage(
|
||||
new String(data.readBytes(data.available()), StandardCharsets.UTF_8),
|
||||
spongePlayer
|
||||
);
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.sk89q.worldedit.command.util.PermissionCondition;
|
||||
import com.sk89q.worldedit.sponge.internal.LocaleResolver;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.enginehub.piston.Command;
|
||||
import org.spongepowered.api.command.CommandCause;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class CommandAdapter implements org.spongepowered.api.command.Command.Raw {
|
||||
private final Command command;
|
||||
|
||||
protected CommandAdapter(Command command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExecute(CommandCause cause) {
|
||||
Set<String> permissions = command.getCondition().as(PermissionCondition.class)
|
||||
.map(PermissionCondition::getPermissions)
|
||||
.orElseGet(Collections::emptySet);
|
||||
|
||||
// Allow commands without permission nodes to always execute.
|
||||
if (permissions.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (String perm : permissions) {
|
||||
if (cause.hasPermission(perm)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Component> shortDescription(CommandCause cause) {
|
||||
return Optional.of(command.getDescription())
|
||||
.map(desc -> SpongeTextAdapter.convert(desc, LocaleResolver.resolveLocale(cause.audience())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Component> extendedDescription(CommandCause cause) {
|
||||
return command.getFooter()
|
||||
.map(footer -> SpongeTextAdapter.convert(footer, LocaleResolver.resolveLocale(cause.audience())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Component> help(@NonNull CommandCause cause) {
|
||||
return Optional.of(command.getFullHelp())
|
||||
.map(help -> SpongeTextAdapter.convert(help, LocaleResolver.resolveLocale(cause.audience())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component usage(CommandCause cause) {
|
||||
return SpongeTextAdapter.convert(command.getUsage(), LocaleResolver.resolveLocale(cause.audience()));
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import org.spongepowered.api.data.persistence.DataQuery;
|
||||
|
||||
/**
|
||||
* Kinda mirrors Sponge Common's Constants class.
|
||||
*
|
||||
* <p>Internal. Do not use.</p>
|
||||
*/
|
||||
public class Constants {
|
||||
public static class Sponge {
|
||||
public static final DataQuery UNSAFE_NBT = DataQuery.of("UnsafeData");
|
||||
|
||||
private Sponge() {
|
||||
}
|
||||
}
|
||||
|
||||
private Constants() {
|
||||
}
|
||||
}
|
@ -1,249 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.sponge.internal.NbtAdapter;
|
||||
import com.sk89q.worldedit.sponge.internal.SpongeTransmogrifier;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.concurrency.LazyReference;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import org.enginehub.linbus.tree.LinCompoundTag;
|
||||
import org.spongepowered.api.ResourceKey;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.data.persistence.DataContainer;
|
||||
import org.spongepowered.api.data.persistence.DataView;
|
||||
import org.spongepowered.api.entity.living.player.Player;
|
||||
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
|
||||
import org.spongepowered.api.item.inventory.ItemStack;
|
||||
import org.spongepowered.api.registry.RegistryKey;
|
||||
import org.spongepowered.api.registry.RegistryReference;
|
||||
import org.spongepowered.api.registry.RegistryTypes;
|
||||
import org.spongepowered.api.world.biome.Biome;
|
||||
import org.spongepowered.api.world.server.ServerLocation;
|
||||
import org.spongepowered.api.world.server.ServerWorld;
|
||||
import org.spongepowered.math.vector.Vector3d;
|
||||
import org.spongepowered.math.vector.Vector3i;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Adapts between Sponge and WorldEdit equivalent objects.
|
||||
*/
|
||||
public class SpongeAdapter {
|
||||
|
||||
public static org.spongepowered.api.block.BlockState adapt(BlockState blockState) {
|
||||
int blockStateId = BlockStateIdAccess.getBlockStateId(blockState);
|
||||
if (!BlockStateIdAccess.isValidInternalId(blockStateId)) {
|
||||
return SpongeTransmogrifier.transmogToMinecraft(blockState);
|
||||
}
|
||||
return (org.spongepowered.api.block.BlockState) Block.stateById(blockStateId);
|
||||
}
|
||||
|
||||
public static BlockState adapt(org.spongepowered.api.block.BlockState blockState) {
|
||||
int blockStateId = Block.getId((net.minecraft.world.level.block.state.BlockState) blockState);
|
||||
BlockState worldEdit = BlockStateIdAccess.getBlockStateById(blockStateId);
|
||||
if (worldEdit == null) {
|
||||
return SpongeTransmogrifier.transmogToWorldEdit(blockState);
|
||||
}
|
||||
return worldEdit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a WorldEdit world from a Sponge world.
|
||||
*
|
||||
* @param world the Sponge world
|
||||
* @return a WorldEdit world
|
||||
*/
|
||||
public static World adapt(ServerWorld world) {
|
||||
checkNotNull(world);
|
||||
return new SpongeWorld(world);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a WorldEdit Player from a Sponge Player.
|
||||
*
|
||||
* @param player The Sponge player
|
||||
* @return The WorldEdit player
|
||||
*/
|
||||
public static SpongePlayer adapt(ServerPlayer player) {
|
||||
Objects.requireNonNull(player);
|
||||
return new SpongePlayer(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Sponge Player from a WorldEdit Player.
|
||||
*
|
||||
* @param player The WorldEdit player
|
||||
* @return The Bukkit player
|
||||
*/
|
||||
public static Player adapt(com.sk89q.worldedit.entity.Player player) {
|
||||
return ((SpongePlayer) player).getPlayer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Sponge world from a WorldEdit world.
|
||||
*
|
||||
* @param world the WorldEdit world
|
||||
* @return a Sponge world
|
||||
*/
|
||||
public static ServerWorld adapt(World world) {
|
||||
checkNotNull(world);
|
||||
if (world instanceof SpongeWorld) {
|
||||
return ((SpongeWorld) world).getWorld();
|
||||
} else {
|
||||
// Currently this is 99% certain to fail, we don't have consistent world name/id mapping
|
||||
ServerWorld match = Sponge.server().worldManager().world(
|
||||
ResourceKey.resolve(world.getName())
|
||||
).orElse(null);
|
||||
if (match != null) {
|
||||
return match;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Can't find a Sponge world for " + world);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static RegistryReference<Biome> adapt(BiomeType biomeType) {
|
||||
return RegistryKey.of(RegistryTypes.BIOME, ResourceKey.resolve(biomeType.id()))
|
||||
.asReference();
|
||||
}
|
||||
|
||||
public static BiomeType adapt(Biome biomeType) {
|
||||
return BiomeType.REGISTRY.get(biomeType.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a WorldEdit location from a Sponge location.
|
||||
*
|
||||
* @param location the Sponge location
|
||||
* @return a WorldEdit location
|
||||
*/
|
||||
public static Location adapt(ServerLocation location, Vector3d rotation) {
|
||||
checkNotNull(location);
|
||||
Vector3 position = asVector(location);
|
||||
return new Location(
|
||||
adapt(location.world()),
|
||||
position,
|
||||
(float) rotation.y(),
|
||||
(float) rotation.x()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Sponge location from a WorldEdit location.
|
||||
*
|
||||
* @param location the WorldEdit location
|
||||
* @return a Sponge location
|
||||
*/
|
||||
public static ServerLocation adapt(Location location) {
|
||||
checkNotNull(location);
|
||||
Vector3 position = location.toVector();
|
||||
return ServerLocation.of(
|
||||
adapt((World) location.getExtent()),
|
||||
position.x(), position.y(), position.z()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Sponge rotation from a WorldEdit location.
|
||||
*
|
||||
* @param location the WorldEdit location
|
||||
* @return a Sponge rotation
|
||||
*/
|
||||
public static Vector3d adaptRotation(Location location) {
|
||||
checkNotNull(location);
|
||||
return new Vector3d(location.getPitch(), location.getYaw(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a WorldEdit Vector from a Sponge location.
|
||||
*
|
||||
* @param location The Sponge location
|
||||
* @return a WorldEdit vector
|
||||
*/
|
||||
public static Vector3 asVector(ServerLocation location) {
|
||||
checkNotNull(location);
|
||||
return Vector3.at(location.x(), location.y(), location.z());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a WorldEdit BlockVector from a Sponge location.
|
||||
*
|
||||
* @param location The Sponge location
|
||||
* @return a WorldEdit vector
|
||||
*/
|
||||
public static BlockVector3 asBlockVector(ServerLocation location) {
|
||||
checkNotNull(location);
|
||||
return BlockVector3.at(location.x(), location.y(), location.z());
|
||||
}
|
||||
|
||||
public static BaseItemStack adapt(ItemStack itemStack) {
|
||||
DataView tag = itemStack.toContainer().getView(Constants.Sponge.UNSAFE_NBT)
|
||||
.orElse(null);
|
||||
return new BaseItemStack(
|
||||
ItemTypes.get(itemStack.type().key(RegistryTypes.ITEM_TYPE).asString()),
|
||||
tag == null ? null : LazyReference.from(() -> NbtAdapter.adaptToWorldEdit(tag)),
|
||||
itemStack.quantity()
|
||||
);
|
||||
}
|
||||
|
||||
public static ItemStack adapt(BaseItemStack itemStack) {
|
||||
ItemStack stack = ItemStack.builder()
|
||||
.itemType(() -> Sponge.game().registry(RegistryTypes.ITEM_TYPE)
|
||||
.value(ResourceKey.resolve(itemStack.getType().id())))
|
||||
.quantity(itemStack.getAmount())
|
||||
.build();
|
||||
LinCompoundTag nbt = itemStack.getNbt();
|
||||
if (nbt != null) {
|
||||
stack.setRawData(
|
||||
DataContainer.createNew(DataView.SafetyMode.NO_DATA_CLONED)
|
||||
.set(Constants.Sponge.UNSAFE_NBT, NbtAdapter.adaptFromWorldEdit(nbt))
|
||||
);
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
public static Direction adapt(org.spongepowered.api.util.Direction direction) {
|
||||
return Direction.valueOf(direction.name());
|
||||
}
|
||||
|
||||
public static Vector3i adaptVector3i(BlockVector3 bv3) {
|
||||
return new Vector3i(bv3.x(), bv3.y(), bv3.z());
|
||||
}
|
||||
|
||||
public static BlockVector3 adaptVector3i(Vector3i vec3i) {
|
||||
return BlockVector3.at(vec3i.x(), vec3i.y(), vec3i.z());
|
||||
}
|
||||
|
||||
private SpongeAdapter() {
|
||||
}
|
||||
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
|
||||
import com.sk89q.worldedit.util.translation.TranslationManager;
|
||||
import com.sk89q.worldedit.world.biome.BiomeData;
|
||||
import com.sk89q.worldedit.world.registry.BiomeRegistry;
|
||||
import org.spongepowered.api.registry.RegistryReference;
|
||||
import org.spongepowered.api.world.biome.Biome;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Provides access to biome data in Sponge.
|
||||
*/
|
||||
class SpongeBiomeRegistry implements BiomeRegistry {
|
||||
|
||||
@Override
|
||||
public Component getRichName(com.sk89q.worldedit.world.biome.BiomeType biomeType) {
|
||||
return TranslatableComponent.of(
|
||||
TranslationManager.makeTranslationKey("biome", biomeType.id())
|
||||
);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Nullable
|
||||
@Override
|
||||
public BiomeData getData(com.sk89q.worldedit.world.biome.BiomeType biome) {
|
||||
return new SpongeBiomeData(SpongeAdapter.adapt(biome));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private static class SpongeBiomeData implements BiomeData {
|
||||
private final RegistryReference<Biome> biome;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param biome the base biome
|
||||
*/
|
||||
private SpongeBiomeData(RegistryReference<Biome> biome) {
|
||||
this.biome = biome;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public String getName() {
|
||||
return biome.location().asString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.registry.BlockCategoryRegistry;
|
||||
import org.spongepowered.api.ResourceKey;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.registry.Registry;
|
||||
import org.spongepowered.api.registry.RegistryTypes;
|
||||
import org.spongepowered.api.tag.Tag;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SpongeBlockCategoryRegistry implements BlockCategoryRegistry {
|
||||
@Override
|
||||
public Set<BlockType> getCategorisedByName(String category) {
|
||||
Registry<org.spongepowered.api.block.BlockType> blockTypeRegistry =
|
||||
Sponge.game().registry(RegistryTypes.BLOCK_TYPE);
|
||||
|
||||
return blockTypeRegistry.taggedValues(Tag.of(RegistryTypes.BLOCK_TYPE, ResourceKey.resolve(category)))
|
||||
.stream()
|
||||
.map(blockType -> BlockType.REGISTRY.get(blockTypeRegistry.valueKey(blockType).formatted()))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
@ -1,183 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.platform.AbstractCommandBlockActor;
|
||||
import com.sk89q.worldedit.session.SessionKey;
|
||||
import com.sk89q.worldedit.util.auth.AuthorizationException;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.block.BlockState;
|
||||
import org.spongepowered.api.block.BlockType;
|
||||
import org.spongepowered.api.block.BlockTypes;
|
||||
import org.spongepowered.api.block.entity.CommandBlock;
|
||||
import org.spongepowered.api.data.Keys;
|
||||
import org.spongepowered.api.scheduler.Task;
|
||||
import org.spongepowered.api.util.Ticks;
|
||||
import org.spongepowered.math.vector.Vector3d;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class SpongeBlockCommandSender extends AbstractCommandBlockActor {
|
||||
private final SpongeWorldEdit worldEdit;
|
||||
private final CommandBlock sender;
|
||||
private final UUID uuid;
|
||||
|
||||
public SpongeBlockCommandSender(SpongeWorldEdit worldEdit, CommandBlock sender) {
|
||||
super(SpongeAdapter.adapt(checkNotNull(sender).serverLocation(), Vector3d.ZERO));
|
||||
checkNotNull(worldEdit);
|
||||
|
||||
this.worldEdit = worldEdit;
|
||||
this.sender = sender;
|
||||
this.uuid = UUID.nameUUIDFromBytes((UUID_PREFIX + sender.name()).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return sender.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printRaw(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
sendMessage(net.kyori.adventure.text.Component.text(part));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void print(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
print(TextComponent.of(part, TextColor.LIGHT_PURPLE));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printDebug(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
print(TextComponent.of(part, TextColor.GRAY));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printError(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
print(TextComponent.of(part, TextColor.RED));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(Component component) {
|
||||
sendMessage(SpongeTextAdapter.convert(component, getLocale()));
|
||||
}
|
||||
|
||||
private void sendMessage(net.kyori.adventure.text.Component textComponent) {
|
||||
this.sender.offer(Keys.LAST_COMMAND_OUTPUT, textComponent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getLocale() {
|
||||
return WorldEdit.getInstance().getConfiguration().defaultLocale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getGroups() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkPermission(String permission) throws AuthorizationException {
|
||||
if (!hasPermission(permission)) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String permission) {
|
||||
return sender.hasPermission(permission);
|
||||
}
|
||||
|
||||
public CommandBlock getSender() {
|
||||
return this.sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionKey getSessionKey() {
|
||||
return new SessionKey() {
|
||||
|
||||
private volatile boolean active = true;
|
||||
|
||||
private void updateActive() {
|
||||
BlockState block = sender.block();
|
||||
if (!sender.serverLocation().world().isChunkLoadedAtBlock(sender.blockPosition(), false)) {
|
||||
active = false;
|
||||
return;
|
||||
}
|
||||
BlockType type = block.type();
|
||||
active = type == BlockTypes.COMMAND_BLOCK.get()
|
||||
|| type == BlockTypes.CHAIN_COMMAND_BLOCK.get()
|
||||
|| type == BlockTypes.REPEATING_COMMAND_BLOCK.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return sender.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
if (Sponge.server().onMainThread()) {
|
||||
// we can update eagerly
|
||||
updateActive();
|
||||
} else {
|
||||
// we should update it eventually
|
||||
Task task = Task.builder().delay(Ticks.zero()).plugin(worldEdit.getPluginContainer()).execute(this::updateActive).build();
|
||||
Sponge.server().scheduler().submit(task);
|
||||
}
|
||||
return active;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPersistent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return uuid;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||
import com.sk89q.worldedit.world.registry.PassthroughBlockMaterial;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.PushReaction;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Sponge block material that pulls as much info as possible from the Minecraft
|
||||
* Material, and passes the rest to another implementation, typically the
|
||||
* bundled block info.
|
||||
*/
|
||||
public class SpongeBlockMaterial extends PassthroughBlockMaterial {
|
||||
|
||||
private final BlockState block;
|
||||
|
||||
public SpongeBlockMaterial(BlockState block, @Nullable BlockMaterial secondary) {
|
||||
super(secondary);
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAir() {
|
||||
return block.isAir() || super.isAir();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpaque() {
|
||||
return block.canOcclude();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean isLiquid() {
|
||||
return block.liquid();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean isSolid() {
|
||||
return block.isSolid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFragileWhenPushed() {
|
||||
return block.getPistonPushReaction() == PushReaction.DESTROY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnpushable() {
|
||||
return block.getPistonPushReaction() == PushReaction.BLOCK;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean isMovementBlocker() {
|
||||
return block.blocksMotion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBurnable() {
|
||||
return block.ignitedByLava();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isToolRequired() {
|
||||
return block.requiresCorrectToolForDrops();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReplacedDuringPlacement() {
|
||||
return block.canBeReplaced();
|
||||
}
|
||||
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.sponge.internal.SpongeTransmogrifier;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||
import com.sk89q.worldedit.world.registry.BundledBlockRegistry;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import org.spongepowered.api.ResourceKey;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.registry.RegistryTypes;
|
||||
import org.spongepowered.api.state.StateProperty;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class SpongeBlockRegistry extends BundledBlockRegistry {
|
||||
|
||||
private final Map<org.spongepowered.api.block.BlockState, SpongeBlockMaterial> materialMap =
|
||||
new HashMap<>();
|
||||
|
||||
@Override
|
||||
public Component getRichName(BlockType blockType) {
|
||||
return SpongeTextAdapter.convert(Sponge.game().registry(RegistryTypes.BLOCK_TYPE)
|
||||
.value(ResourceKey.resolve(blockType.id())).asComponent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockMaterial getMaterial(BlockType blockType) {
|
||||
org.spongepowered.api.block.BlockType spongeBlockType =
|
||||
Sponge.game().registry(RegistryTypes.BLOCK_TYPE)
|
||||
.value(ResourceKey.resolve(blockType.id()));
|
||||
return materialMap.computeIfAbsent(
|
||||
spongeBlockType.defaultState(),
|
||||
m -> {
|
||||
net.minecraft.world.level.block.state.BlockState blockState =
|
||||
(net.minecraft.world.level.block.state.BlockState) m;
|
||||
return new SpongeBlockMaterial(
|
||||
blockState,
|
||||
super.getMaterial(blockType)
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ? extends Property<?>> getProperties(BlockType blockType) {
|
||||
org.spongepowered.api.block.BlockType spongeBlockType =
|
||||
Sponge.game().registry(RegistryTypes.BLOCK_TYPE)
|
||||
.value(ResourceKey.resolve(blockType.id()));
|
||||
Map<String, Property<?>> map = new TreeMap<>();
|
||||
Collection<StateProperty<?>> propertyKeys = spongeBlockType
|
||||
.defaultState().stateProperties();
|
||||
for (StateProperty<?> key : propertyKeys) {
|
||||
map.put(key.name(), SpongeTransmogrifier.transmogToWorldEditProperty(key));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OptionalInt getInternalBlockStateId(BlockState state) {
|
||||
org.spongepowered.api.block.BlockState equivalent = SpongeAdapter.adapt(state);
|
||||
return OptionalInt.of(Block.getId(
|
||||
(net.minecraft.world.level.block.state.BlockState) equivalent
|
||||
));
|
||||
}
|
||||
}
|
@ -1,172 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.internal.cui.CUIEvent;
|
||||
import com.sk89q.worldedit.session.SessionKey;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import org.spongepowered.api.entity.living.player.Player;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class SpongeCommandSender implements Actor {
|
||||
|
||||
/**
|
||||
* One time generated ID.
|
||||
*/
|
||||
private static final UUID DEFAULT_ID = UUID.fromString("a233eb4b-4cab-42cd-9fd9-7e7b9a3f74be");
|
||||
|
||||
private final Audience sender;
|
||||
|
||||
public SpongeCommandSender(Audience sender) {
|
||||
checkNotNull(sender);
|
||||
checkArgument(
|
||||
!(sender instanceof Player),
|
||||
"Players should be wrapped using the specialized class"
|
||||
);
|
||||
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return DEFAULT_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Console";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printRaw(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
sender.sendMessage(net.kyori.adventure.text.Component.text(part));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void print(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
print(TextComponent.of(part, TextColor.LIGHT_PURPLE));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printDebug(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
print(TextComponent.of(part, TextColor.GRAY));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printError(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
print(TextComponent.of(part, TextColor.RED));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(Component component) {
|
||||
sender.sendMessage(SpongeTextAdapter.convert(component, getLocale()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDestroyBedrock() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getGroups() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String perm) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkPermission(String permission) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlayer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File openFileOpenDialog(String[] extensions) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File openFileSaveDialog(String[] extensions) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchCUIEvent(CUIEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getLocale() {
|
||||
return WorldEdit.getInstance().getConfiguration().defaultLocale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionKey getSessionKey() {
|
||||
return new SessionKey() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Console";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPersistent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return DEFAULT_ID;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.entity.metadata.EntityProperties;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.sponge.internal.NbtAdapter;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.concurrency.LazyReference;
|
||||
import com.sk89q.worldedit.world.NullWorld;
|
||||
import com.sk89q.worldedit.world.entity.EntityType;
|
||||
import org.spongepowered.api.data.persistence.DataView;
|
||||
import org.spongepowered.api.registry.RegistryTypes;
|
||||
import org.spongepowered.api.world.server.ServerLocation;
|
||||
import org.spongepowered.math.vector.Vector3d;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
class SpongeEntity implements Entity {
|
||||
|
||||
private final WeakReference<org.spongepowered.api.entity.Entity> entityRef;
|
||||
|
||||
SpongeEntity(org.spongepowered.api.entity.Entity entity) {
|
||||
checkNotNull(entity);
|
||||
this.entityRef = new WeakReference<>(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseEntity getState() {
|
||||
org.spongepowered.api.entity.Entity entity = entityRef.get();
|
||||
if (entity == null || entity.vehicle().isPresent()) {
|
||||
return null;
|
||||
}
|
||||
EntityType entityType = EntityType.REGISTRY.get(entity.type().key(RegistryTypes.ENTITY_TYPE).asString());
|
||||
if (entityType == null) {
|
||||
return null;
|
||||
}
|
||||
DataView dataView = entity.toContainer().getView(Constants.Sponge.UNSAFE_NBT)
|
||||
.orElse(null);
|
||||
return new BaseEntity(
|
||||
entityType,
|
||||
dataView == null ? null : LazyReference.from(() -> NbtAdapter.adaptToWorldEdit(dataView))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
org.spongepowered.api.entity.Entity entity = entityRef.get();
|
||||
if (entity != null) {
|
||||
ServerLocation entityLoc = entity.serverLocation();
|
||||
Vector3d entityRot = entity.rotation();
|
||||
|
||||
return SpongeAdapter.adapt(entityLoc, entityRot);
|
||||
} else {
|
||||
return new Location(NullWorld.getInstance());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLocation(Location location) {
|
||||
org.spongepowered.api.entity.Entity entity = entityRef.get();
|
||||
if (entity != null) {
|
||||
return entity.setLocation(SpongeAdapter.adapt(location));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Extent getExtent() {
|
||||
org.spongepowered.api.entity.Entity entity = entityRef.get();
|
||||
if (entity != null) {
|
||||
return SpongeAdapter.adapt(entity.serverLocation().world());
|
||||
} else {
|
||||
return NullWorld.getInstance();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove() {
|
||||
org.spongepowered.api.entity.Entity entity = entityRef.get();
|
||||
if (entity != null) {
|
||||
entity.remove();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T getFacet(Class<? extends T> cls) {
|
||||
org.spongepowered.api.entity.Entity entity = entityRef.get();
|
||||
if (entity != null) {
|
||||
if (EntityProperties.class.isAssignableFrom(cls)) {
|
||||
return (T) new SpongeEntityProperties(entity);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,155 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.sk89q.worldedit.entity.metadata.EntityProperties;
|
||||
import org.spongepowered.api.data.Keys;
|
||||
import org.spongepowered.api.entity.Entity;
|
||||
import org.spongepowered.api.entity.ExperienceOrb;
|
||||
import org.spongepowered.api.entity.FallingBlock;
|
||||
import org.spongepowered.api.entity.Item;
|
||||
import org.spongepowered.api.entity.explosive.fused.PrimedTNT;
|
||||
import org.spongepowered.api.entity.hanging.ItemFrame;
|
||||
import org.spongepowered.api.entity.hanging.Painting;
|
||||
import org.spongepowered.api.entity.living.Ambient;
|
||||
import org.spongepowered.api.entity.living.ArmorStand;
|
||||
import org.spongepowered.api.entity.living.ComplexLivingPart;
|
||||
import org.spongepowered.api.entity.living.Humanoid;
|
||||
import org.spongepowered.api.entity.living.Living;
|
||||
import org.spongepowered.api.entity.living.animal.Animal;
|
||||
import org.spongepowered.api.entity.living.aquatic.Aquatic;
|
||||
import org.spongepowered.api.entity.living.golem.Golem;
|
||||
import org.spongepowered.api.entity.living.player.Player;
|
||||
import org.spongepowered.api.entity.living.trader.Trader;
|
||||
import org.spongepowered.api.entity.projectile.Projectile;
|
||||
import org.spongepowered.api.entity.vehicle.Boat;
|
||||
import org.spongepowered.api.entity.vehicle.minecart.Minecart;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class SpongeEntityProperties implements EntityProperties {
|
||||
|
||||
private final Entity entity;
|
||||
|
||||
public SpongeEntityProperties(Entity entity) {
|
||||
checkNotNull(entity);
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlayerDerived() {
|
||||
return entity instanceof Humanoid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProjectile() {
|
||||
return entity instanceof Projectile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItem() {
|
||||
return entity instanceof Item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFallingBlock() {
|
||||
return entity instanceof FallingBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPainting() {
|
||||
return entity instanceof Painting;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemFrame() {
|
||||
return entity instanceof ItemFrame;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBoat() {
|
||||
return entity instanceof Boat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMinecart() {
|
||||
return entity instanceof Minecart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTNT() {
|
||||
return entity instanceof PrimedTNT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExperienceOrb() {
|
||||
return entity instanceof ExperienceOrb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLiving() {
|
||||
return entity instanceof Living;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnimal() {
|
||||
return entity instanceof Animal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbient() {
|
||||
return entity instanceof Ambient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNPC() {
|
||||
return entity instanceof Trader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGolem() {
|
||||
return entity instanceof Golem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTamed() {
|
||||
return entity.get(Keys.IS_TAMED).orElse(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTagged() {
|
||||
return entity.get(Keys.CUSTOM_NAME).isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isArmorStand() {
|
||||
return entity instanceof ArmorStand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPasteable() {
|
||||
return !(entity instanceof Player || entity instanceof ComplexLivingPart);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWaterCreature() {
|
||||
return entity instanceof Aquatic;
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.registry.ItemCategoryRegistry;
|
||||
import org.spongepowered.api.ResourceKey;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.block.BlockType;
|
||||
import org.spongepowered.api.registry.Registry;
|
||||
import org.spongepowered.api.registry.RegistryTypes;
|
||||
import org.spongepowered.api.tag.Tag;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SpongeItemCategoryRegistry implements ItemCategoryRegistry {
|
||||
@Override
|
||||
public Set<ItemType> getCategorisedByName(String category) {
|
||||
Registry<org.spongepowered.api.item.ItemType> itemTypeRegistry =
|
||||
Sponge.game().registry(RegistryTypes.ITEM_TYPE);
|
||||
|
||||
return itemTypeRegistry.taggedValues(Tag.of(RegistryTypes.ITEM_TYPE, ResourceKey.resolve(category)))
|
||||
.stream()
|
||||
.map(itemType -> ItemType.REGISTRY.get(itemTypeRegistry.valueKey(itemType).formatted()))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.registry.BundledItemRegistry;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.spongepowered.api.ResourceKey;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.registry.RegistryTypes;
|
||||
|
||||
public class SpongeItemRegistry extends BundledItemRegistry {
|
||||
|
||||
@Override
|
||||
public Component getRichName(ItemType itemType) {
|
||||
return SpongeTextAdapter.convert(Sponge.game().registry(RegistryTypes.ITEM_TYPE)
|
||||
.value(ResourceKey.resolve(itemType.id())).asComponent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getRichName(BaseItemStack itemStack) {
|
||||
return TranslatableComponent.of(
|
||||
((ItemStack) (Object) SpongeAdapter.adapt(itemStack)).getDescriptionId()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
|
||||
import org.spongepowered.api.service.permission.PermissionDescription;
|
||||
import org.spongepowered.api.service.permission.PermissionService;
|
||||
import org.spongepowered.api.service.permission.SubjectReference;
|
||||
|
||||
public class SpongePermissionsProvider {
|
||||
|
||||
public boolean hasPermission(ServerPlayer player, String permission) {
|
||||
return player.hasPermission(permission);
|
||||
}
|
||||
|
||||
public void registerPermission(String permission) {
|
||||
Sponge.game().serviceProvider().registration(PermissionService.class).ifPresent((permissionService -> {
|
||||
PermissionDescription.Builder permissionBuilder = permissionService.service()
|
||||
.newDescriptionBuilder(SpongeWorldEdit.inst().getPluginContainer());
|
||||
permissionBuilder.id(permission).register();
|
||||
}));
|
||||
}
|
||||
|
||||
public String[] getGroups(ServerPlayer player) {
|
||||
return player.parents().stream()
|
||||
.map(SubjectReference::subjectIdentifier)
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
}
|
@ -1,200 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.platform.AbstractPlatform;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.extension.platform.MultiUserPlatform;
|
||||
import com.sk89q.worldedit.extension.platform.Preference;
|
||||
import com.sk89q.worldedit.sponge.config.SpongeConfiguration;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.registry.Registries;
|
||||
import org.enginehub.piston.CommandManager;
|
||||
import org.spongepowered.api.ResourceKey;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
|
||||
import org.spongepowered.api.registry.RegistryTypes;
|
||||
import org.spongepowered.api.scheduler.Task;
|
||||
import org.spongepowered.api.util.Ticks;
|
||||
import org.spongepowered.api.world.server.ServerWorld;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
class SpongePlatform extends AbstractPlatform implements MultiUserPlatform {
|
||||
|
||||
private final SpongeWorldEdit mod;
|
||||
private boolean hookingEvents = false;
|
||||
private int nextTaskId = 0;
|
||||
|
||||
SpongePlatform(SpongeWorldEdit mod) {
|
||||
this.mod = mod;
|
||||
}
|
||||
|
||||
boolean isHookingEvents() {
|
||||
return hookingEvents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Registries getRegistries() {
|
||||
return SpongeRegistries.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDataVersion() {
|
||||
return Sponge.platform().minecraftVersion().dataVersion().orElse(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidMobType(String type) {
|
||||
return Sponge.game().registry(RegistryTypes.ENTITY_TYPE)
|
||||
.findValue(ResourceKey.resolve(type)).isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
getConfiguration().load();
|
||||
super.reload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int schedule(long delay, long period, Runnable task) {
|
||||
Sponge.server().scheduler().submit(Task.builder()
|
||||
.delay(Ticks.of(delay))
|
||||
.interval(Ticks.of(period))
|
||||
.execute(task)
|
||||
.plugin(SpongeWorldEdit.inst().getPluginContainer())
|
||||
.build());
|
||||
return nextTaskId++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends com.sk89q.worldedit.world.World> getWorlds() {
|
||||
Collection<ServerWorld> worlds = Sponge.server().worldManager().worlds();
|
||||
List<com.sk89q.worldedit.world.World> ret = new ArrayList<>(worlds.size());
|
||||
for (ServerWorld world : worlds) {
|
||||
ret.add(SpongeAdapter.adapt(world));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Player matchPlayer(Player player) {
|
||||
if (player instanceof SpongePlayer) {
|
||||
return player;
|
||||
} else {
|
||||
Optional<ServerPlayer> optPlayer = Sponge.server().player(player.getUniqueId());
|
||||
return optPlayer.map(SpongePlayer::new).orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public World matchWorld(World world) {
|
||||
if (world instanceof SpongeWorld) {
|
||||
return world;
|
||||
} else {
|
||||
// TODO this needs fixing for world name shenanigans
|
||||
for (ServerWorld spongeWorld : Sponge.server().worldManager().worlds()) {
|
||||
if (spongeWorld.key().toString().equals(world.getName())) {
|
||||
return SpongeAdapter.adapt(spongeWorld);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerCommands(CommandManager manager) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGameHooksEnabled(boolean enabled) {
|
||||
this.hookingEvents = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpongeConfiguration getConfiguration() {
|
||||
return mod.getConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return mod.getInternalVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlatformName() {
|
||||
return "Sponge-Official";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlatformVersion() {
|
||||
return mod.getInternalVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return "enginehub:sponge";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Capability, Preference> getCapabilities() {
|
||||
Map<Capability, Preference> capabilities = new EnumMap<>(Capability.class);
|
||||
capabilities.put(Capability.CONFIGURATION, Preference.NORMAL);
|
||||
capabilities.put(Capability.WORLDEDIT_CUI, Preference.NORMAL);
|
||||
capabilities.put(Capability.GAME_HOOKS, Preference.NORMAL);
|
||||
capabilities.put(Capability.PERMISSIONS, Preference.NORMAL);
|
||||
capabilities.put(Capability.USER_COMMANDS, Preference.NORMAL);
|
||||
capabilities.put(Capability.WORLD_EDITING, Preference.PREFERRED);
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SideEffect> getSupportedSideEffects() {
|
||||
return ImmutableSet.of(
|
||||
SideEffect.UPDATE, SideEffect.ENTITY_AI, SideEffect.LIGHTING, SideEffect.NEIGHBORS
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTickCount() {
|
||||
return Sponge.server().runningTimeTicks().ticks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Actor> getConnectedUsers() {
|
||||
return Sponge.server().onlinePlayers().stream().map(SpongePlayer::new).collect(toList());
|
||||
}
|
||||
}
|
@ -1,308 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.sk89q.util.StringUtil;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.extension.platform.AbstractPlayerActor;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.internal.cui.CUIEvent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.session.SessionKey;
|
||||
import com.sk89q.worldedit.sponge.internal.NbtAdapter;
|
||||
import com.sk89q.worldedit.util.HandSide;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.gamemode.GameMode;
|
||||
import com.sk89q.worldedit.world.gamemode.GameModes;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.world.level.block.entity.StructureBlockEntity;
|
||||
import org.enginehub.linbus.tree.LinCompoundTag;
|
||||
import org.spongepowered.api.ResourceKey;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.block.BlockState;
|
||||
import org.spongepowered.api.data.Keys;
|
||||
import org.spongepowered.api.data.type.HandTypes;
|
||||
import org.spongepowered.api.entity.living.player.Player;
|
||||
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
|
||||
import org.spongepowered.api.item.inventory.ItemStack;
|
||||
import org.spongepowered.api.registry.RegistryTypes;
|
||||
import org.spongepowered.api.world.server.ServerLocation;
|
||||
import org.spongepowered.math.vector.Vector3d;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class SpongePlayer extends AbstractPlayerActor {
|
||||
private static final int STRUCTURE_BLOCK_PACKET_ID = 7;
|
||||
|
||||
private final ServerPlayer player;
|
||||
|
||||
protected SpongePlayer(ServerPlayer player) {
|
||||
this.player = player;
|
||||
ThreadSafeCache.getInstance().getOnlineIds().add(getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return player.uniqueId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseItemStack getItemInHand(HandSide handSide) {
|
||||
ItemStack is = this.player.itemInHand(
|
||||
handSide == HandSide.MAIN_HAND ? HandTypes.MAIN_HAND : HandTypes.OFF_HAND
|
||||
);
|
||||
return SpongeAdapter.adapt(is);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.player.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return LegacyComponentSerializer.legacySection().serialize(player.displayName().get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseEntity getState() {
|
||||
throw new UnsupportedOperationException("Cannot create a state from this object");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
ServerLocation entityLoc = this.player.serverLocation();
|
||||
Vector3d entityRot = this.player.rotation();
|
||||
|
||||
return SpongeAdapter.adapt(entityLoc, entityRot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLocation(Location location) {
|
||||
return player.setLocation(SpongeAdapter.adapt(location));
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.sk89q.worldedit.world.World getWorld() {
|
||||
return SpongeAdapter.adapt(player.serverLocation().world());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void giveItem(BaseItemStack itemStack) {
|
||||
this.player.inventory().offer(SpongeAdapter.adapt(itemStack));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchCUIEvent(CUIEvent event) {
|
||||
String[] params = event.getParameters();
|
||||
String send = event.getTypeId();
|
||||
if (params.length > 0) {
|
||||
send = send + "|" + StringUtil.joinString(params, "|");
|
||||
}
|
||||
|
||||
String finalData = send;
|
||||
CUIChannelHandler.channel().play().sendTo(
|
||||
player,
|
||||
buffer -> buffer.writeBytes(finalData.getBytes(StandardCharsets.UTF_8))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printRaw(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
this.player.sendMessage(LegacyComponentSerializer.legacySection().deserialize(part));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printDebug(String msg) {
|
||||
sendColorized(msg, NamedTextColor.GRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void print(String msg) {
|
||||
sendColorized(msg, NamedTextColor.LIGHT_PURPLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void printError(String msg) {
|
||||
sendColorized(msg, NamedTextColor.RED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(Component component) {
|
||||
player.sendMessage(SpongeTextAdapter.convert(component, getLocale()));
|
||||
}
|
||||
|
||||
private void sendColorized(String msg, TextColor formatting) {
|
||||
for (String part : msg.split("\n")) {
|
||||
this.player.sendMessage(
|
||||
LegacyComponentSerializer.legacySection().deserialize(part).color(formatting)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trySetPosition(Vector3 pos, float pitch, float yaw) {
|
||||
ServerLocation loc = ServerLocation.of(
|
||||
this.player.world(), pos.x(), pos.y(), pos.z()
|
||||
);
|
||||
|
||||
return this.player.setLocationAndRotation(loc, new Vector3d(pitch, yaw, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getGroups() {
|
||||
return SpongeWorldEdit.inst().getPermissionsProvider().getGroups(this.player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockBag getInventoryBlockBag() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String perm) {
|
||||
return SpongeWorldEdit.inst().getPermissionsProvider().hasPermission(player, perm);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T getFacet(Class<? extends T> cls) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameMode getGameMode() {
|
||||
return GameModes.get(player.gameMode().get().key(RegistryTypes.GAME_MODE).asString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGameMode(GameMode gameMode) {
|
||||
player.gameMode().set(
|
||||
Sponge.game().registry(RegistryTypes.GAME_MODE).value(
|
||||
ResourceKey.resolve(gameMode.id())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowedToFly() {
|
||||
return player.get(Keys.CAN_FLY).orElse(super.isAllowedToFly());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFlying(boolean flying) {
|
||||
player.offer(Keys.IS_FLYING, flying);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> void sendFakeBlock(BlockVector3 pos, B block) {
|
||||
if (block == null) {
|
||||
player.resetBlockChange(pos.x(), pos.y(), pos.z());
|
||||
} else {
|
||||
BlockState spongeBlock = SpongeAdapter.adapt(block.toImmutableState());
|
||||
player.sendBlockChange(pos.x(), pos.y(), pos.z(), spongeBlock);
|
||||
if (block instanceof final BaseBlock baseBlock
|
||||
&& block.getBlockType().equals(com.sk89q.worldedit.world.block.BlockTypes.STRUCTURE_BLOCK)) {
|
||||
final LinCompoundTag nbtData = baseBlock.getNbt();
|
||||
if (nbtData != null) {
|
||||
net.minecraft.world.level.block.state.BlockState nativeBlock =
|
||||
(net.minecraft.world.level.block.state.BlockState) spongeBlock;
|
||||
net.minecraft.nbt.CompoundTag nativeNbtData = NbtAdapter.adaptNMSToWorldEdit(nbtData);
|
||||
net.minecraft.server.level.ServerPlayer nativePlayer =
|
||||
((net.minecraft.server.level.ServerPlayer) player);
|
||||
|
||||
StructureBlockEntity structureBlockEntity =
|
||||
new StructureBlockEntity(new BlockPos(pos.x(), pos.y(), pos.z()), nativeBlock);
|
||||
structureBlockEntity.load(nativeNbtData);
|
||||
nativePlayer.connection.send(
|
||||
ClientboundBlockEntityDataPacket.create(structureBlockEntity, it -> nativeNbtData));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getLocale() {
|
||||
return player.locale();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionKey getSessionKey() {
|
||||
return new SessionKeyImpl(player);
|
||||
}
|
||||
|
||||
static class SessionKeyImpl implements SessionKey {
|
||||
// If not static, this will leak a reference
|
||||
|
||||
private final UUID uuid;
|
||||
private final String name;
|
||||
|
||||
SessionKeyImpl(Player player) {
|
||||
this.uuid = player.uniqueId();
|
||||
this.name = player.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
// We can't directly check if the player is online because
|
||||
// the list of players is not thread safe
|
||||
return ThreadSafeCache.getInstance().getOnlineIds().contains(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPersistent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.sk89q.worldedit.world.registry.BiomeRegistry;
|
||||
import com.sk89q.worldedit.world.registry.BlockCategoryRegistry;
|
||||
import com.sk89q.worldedit.world.registry.BlockRegistry;
|
||||
import com.sk89q.worldedit.world.registry.BundledRegistries;
|
||||
import com.sk89q.worldedit.world.registry.ItemCategoryRegistry;
|
||||
import com.sk89q.worldedit.world.registry.ItemRegistry;
|
||||
|
||||
/**
|
||||
* World data for the Sponge platform.
|
||||
*/
|
||||
class SpongeRegistries extends BundledRegistries {
|
||||
|
||||
private static final SpongeRegistries INSTANCE = new SpongeRegistries();
|
||||
|
||||
public static SpongeRegistries getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private final BiomeRegistry biomeRegistry = new SpongeBiomeRegistry();
|
||||
private final BlockRegistry blockRegistry = new SpongeBlockRegistry();
|
||||
private final BlockCategoryRegistry blockCategoryRegistry = new SpongeBlockCategoryRegistry();
|
||||
private final ItemRegistry itemRegistry = new SpongeItemRegistry();
|
||||
private final ItemCategoryRegistry itemCategoryRegistry = new SpongeItemCategoryRegistry();
|
||||
|
||||
@Override
|
||||
public BiomeRegistry getBiomeRegistry() {
|
||||
return biomeRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockRegistry getBlockRegistry() {
|
||||
return blockRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockCategoryRegistry getBlockCategoryRegistry() {
|
||||
return blockCategoryRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemRegistry getItemRegistry() {
|
||||
return itemRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemCategoryRegistry getItemCategoryRegistry() {
|
||||
return itemCategoryRegistry;
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.sk89q.worldedit.util.formatting.WorldEditText;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.serializer.gson.GsonComponentSerializer;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class SpongeTextAdapter {
|
||||
|
||||
public static net.kyori.adventure.text.Component convert(Component component, Locale locale) {
|
||||
component = WorldEditText.format(component, locale);
|
||||
return net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson()
|
||||
.deserialize(GsonComponentSerializer.INSTANCE.serialize(component));
|
||||
}
|
||||
|
||||
public static Component convert(net.kyori.adventure.text.Component component) {
|
||||
return GsonComponentSerializer.INSTANCE.deserialize(
|
||||
net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson()
|
||||
.serialize(component)
|
||||
);
|
||||
}
|
||||
|
||||
private SpongeTextAdapter() {
|
||||
}
|
||||
}
|
@ -1,507 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.sponge.internal.NbtAdapter;
|
||||
import com.sk89q.worldedit.sponge.internal.SpongeWorldNativeAccess;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import com.sk89q.worldedit.world.AbstractWorld;
|
||||
import com.sk89q.worldedit.world.RegenOptions;
|
||||
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;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import com.sk89q.worldedit.world.weather.WeatherType;
|
||||
import com.sk89q.worldedit.world.weather.WeatherTypes;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.data.worldgen.features.EndFeatures;
|
||||
import net.minecraft.data.worldgen.features.TreeFeatures;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.enginehub.linbus.tree.LinCompoundTag;
|
||||
import org.enginehub.linbus.tree.LinIntTag;
|
||||
import org.enginehub.linbus.tree.LinStringTag;
|
||||
import org.spongepowered.api.ResourceKey;
|
||||
import org.spongepowered.api.Server;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.block.entity.BlockEntity;
|
||||
import org.spongepowered.api.block.entity.BlockEntityArchetype;
|
||||
import org.spongepowered.api.block.entity.BlockEntityType;
|
||||
import org.spongepowered.api.data.Keys;
|
||||
import org.spongepowered.api.entity.EntityArchetype;
|
||||
import org.spongepowered.api.entity.EntityType;
|
||||
import org.spongepowered.api.entity.EntityTypes;
|
||||
import org.spongepowered.api.entity.Item;
|
||||
import org.spongepowered.api.registry.RegistryTypes;
|
||||
import org.spongepowered.api.util.Ticks;
|
||||
import org.spongepowered.api.world.BlockChangeFlags;
|
||||
import org.spongepowered.api.world.LightTypes;
|
||||
import org.spongepowered.api.world.SerializationBehavior;
|
||||
import org.spongepowered.api.world.server.ServerLocation;
|
||||
import org.spongepowered.api.world.server.ServerWorld;
|
||||
import org.spongepowered.api.world.server.WorldTemplate;
|
||||
import org.spongepowered.api.world.volume.stream.StreamOptions;
|
||||
import org.spongepowered.math.vector.Vector3d;
|
||||
import org.spongepowered.math.vector.Vector3i;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* An adapter to Minecraft worlds for WorldEdit.
|
||||
*/
|
||||
public final class SpongeWorld extends AbstractWorld {
|
||||
|
||||
private static final RandomSource random = RandomSource.create();
|
||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||
|
||||
private final WeakReference<ServerWorld> worldRef;
|
||||
private final SpongeWorldNativeAccess worldNativeAccess;
|
||||
|
||||
/**
|
||||
* Construct a new world.
|
||||
*
|
||||
* @param world the world
|
||||
*/
|
||||
SpongeWorld(ServerWorld world) {
|
||||
checkNotNull(world);
|
||||
this.worldRef = new WeakReference<>(world);
|
||||
this.worldNativeAccess = new SpongeWorldNativeAccess(new WeakReference<>((ServerLevel) world));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the underlying handle to the world.
|
||||
*
|
||||
* @return the world
|
||||
* @throws RuntimeException thrown if a reference to the world was lost (i.e. world was
|
||||
* unloaded)
|
||||
*/
|
||||
ServerWorld getWorld() {
|
||||
ServerWorld world = worldRef.get();
|
||||
if (world != null) {
|
||||
return world;
|
||||
} else {
|
||||
throw new RuntimeException("The reference to the world was lost (i.e. the world may have been unloaded)");
|
||||
}
|
||||
}
|
||||
|
||||
// This is sus but leaving it for later world name/id reworks
|
||||
@Override
|
||||
public String getName() {
|
||||
return getWorld().key().asString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return getWorld().key().asString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getStoragePath() {
|
||||
return getWorld().directory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 position) {
|
||||
return SpongeAdapter.adapt(getWorld().block(
|
||||
position.x(), position.y(), position.z()
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
BlockEntity blockEntity = getWorld().blockEntity(
|
||||
position.x(), position.y(), position.z()
|
||||
).orElse(null);
|
||||
LinCompoundTag blockEntityData = null;
|
||||
if (blockEntity != null) {
|
||||
BlockEntityArchetype blockEntityArchetype = blockEntity.createArchetype();
|
||||
BlockEntityType blockEntityType = blockEntityArchetype.blockEntityType();
|
||||
ResourceKey blockEntityId = blockEntityType.key(RegistryTypes.BLOCK_ENTITY_TYPE);
|
||||
blockEntityData = NbtAdapter.adaptToWorldEdit(blockEntityArchetype.blockEntityData());
|
||||
|
||||
// Add ID and position since Sponge's #blockEntityData does not save metadata
|
||||
LinCompoundTag.Builder fullBlockEntityDataBuilder = blockEntityData.toBuilder();
|
||||
fullBlockEntityDataBuilder.put("id", LinStringTag.of(blockEntityId.formatted()));
|
||||
fullBlockEntityDataBuilder.put("x", LinIntTag.of(position.x()));
|
||||
fullBlockEntityDataBuilder.put("y", LinIntTag.of(position.y()));
|
||||
fullBlockEntityDataBuilder.put("z", LinIntTag.of(position.z()));
|
||||
blockEntityData = fullBlockEntityDataBuilder.build();
|
||||
}
|
||||
return getBlock(position).toBaseBlock(blockEntityData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
|
||||
checkNotNull(position);
|
||||
checkNotNull(block);
|
||||
|
||||
ServerWorld world = getWorld();
|
||||
|
||||
org.spongepowered.api.block.BlockState newState = SpongeAdapter.adapt(block.toImmutableState());
|
||||
|
||||
boolean didSet = world.setBlock(
|
||||
position.x(), position.y(), position.z(),
|
||||
newState,
|
||||
BlockChangeFlags.NONE
|
||||
.withUpdateNeighbors(sideEffects.shouldApply(SideEffect.NEIGHBORS))
|
||||
.withNotifyClients(true)
|
||||
.withPhysics(sideEffects.shouldApply(SideEffect.UPDATE))
|
||||
.withNotifyObservers(sideEffects.shouldApply(SideEffect.UPDATE))
|
||||
.withLightingUpdates(sideEffects.shouldApply(SideEffect.LIGHTING))
|
||||
.withPathfindingUpdates(sideEffects.shouldApply(SideEffect.ENTITY_AI))
|
||||
.withNeighborDropsAllowed(false)
|
||||
.withBlocksMoving(false)
|
||||
.withForcedReRender(false)
|
||||
.withIgnoreRender(false)
|
||||
);
|
||||
if (!didSet) {
|
||||
// still update NBT if the block is the same
|
||||
if (world.block(position.x(), position.y(), position.z()) == newState) {
|
||||
didSet = block.toBaseBlock().getNbt() != null;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the TileEntity
|
||||
if (didSet && block instanceof BaseBlock baseBlock) {
|
||||
LinCompoundTag nbt = baseBlock.getNbt();
|
||||
if (nbt != null) {
|
||||
BlockEntityArchetype.builder()
|
||||
.blockEntity(
|
||||
Sponge.game().registry(RegistryTypes.BLOCK_ENTITY_TYPE)
|
||||
.<BlockEntityType>value(ResourceKey.resolve(baseBlock.getNbtId()))
|
||||
)
|
||||
.blockEntityData(NbtAdapter.adaptFromWorldEdit(nbt))
|
||||
.state(newState)
|
||||
.build()
|
||||
.apply(ServerLocation.of(world, position.x(), position.y(), position.z()));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<SideEffect> applySideEffects(BlockVector3 position, com.sk89q.worldedit.world.block.BlockState previousType, SideEffectSet sideEffectSet) throws WorldEditException {
|
||||
checkNotNull(position);
|
||||
|
||||
worldNativeAccess.applySideEffects(position, previousType, sideEffectSet);
|
||||
|
||||
return Sets.intersection(
|
||||
SpongeWorldEdit.inst().getInternalPlatform().getSupportedSideEffects(),
|
||||
sideEffectSet.getSideEffectsToApply()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearContainerBlockContents(BlockVector3 position) {
|
||||
getWorld().removeBlockEntity(position.x(), position.y(), position.z());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean regenerate(Region region, Extent extent, RegenOptions options) {
|
||||
Server server = Sponge.server();
|
||||
|
||||
final String id = "worldedittemp_" + getWorld().key().value();
|
||||
|
||||
WorldTemplate tempWorldProperties = WorldTemplate.builder().from(getWorld())
|
||||
.key(ResourceKey.of("worldedit", id))
|
||||
.add(Keys.IS_LOAD_ON_STARTUP, false)
|
||||
.add(Keys.SERIALIZATION_BEHAVIOR, SerializationBehavior.NONE)
|
||||
.add(Keys.SEED, options.getSeed().orElse(getWorld().properties().worldGenerationConfig().seed()))
|
||||
.build();
|
||||
|
||||
ServerWorld tempWorld;
|
||||
try {
|
||||
tempWorld = server.worldManager().loadWorld(tempWorldProperties).get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
LOGGER.error("Failed to load temp world", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// Pre-gen all the chunks
|
||||
// We need to also pull one more chunk in every direction
|
||||
CuboidRegion expandedPreGen = new CuboidRegion(region.getMinimumPoint().subtract(16, 16, 16), region.getMaximumPoint().add(16, 16, 16));
|
||||
for (BlockVector3 chunk : expandedPreGen.getChunkCubes()) {
|
||||
tempWorld.loadChunk(chunk.x(), chunk.y(), chunk.z(), true);
|
||||
}
|
||||
|
||||
World from = SpongeAdapter.adapt(tempWorld);
|
||||
for (BlockVector3 vec : region) {
|
||||
extent.setBlock(vec, from.getFullBlock(vec));
|
||||
if (options.shouldRegenBiomes()) {
|
||||
extent.setBiome(vec, from.getBiome(vec));
|
||||
}
|
||||
}
|
||||
} catch (WorldEditException e) {
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
// Remove temp world
|
||||
server.worldManager().unloadWorld(tempWorldProperties.key()).thenRun(() -> server.worldManager().deleteWorld(tempWorldProperties.key()));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private static net.minecraft.resources.ResourceKey<ConfiguredFeature<?, ?>> createTreeFeatureGenerator(TreeGenerator.TreeType type) {
|
||||
return switch (type) {
|
||||
// Based off of the SaplingGenerator class, as well as uses of DefaultBiomeFeatures fields
|
||||
case TREE -> TreeFeatures.OAK;
|
||||
case BIG_TREE -> TreeFeatures.FANCY_OAK;
|
||||
case REDWOOD -> TreeFeatures.SPRUCE;
|
||||
case TALL_REDWOOD -> TreeFeatures.MEGA_SPRUCE;
|
||||
case MEGA_REDWOOD -> TreeFeatures.MEGA_PINE;
|
||||
case BIRCH -> TreeFeatures.BIRCH;
|
||||
case JUNGLE -> TreeFeatures.MEGA_JUNGLE_TREE;
|
||||
case SMALL_JUNGLE -> TreeFeatures.JUNGLE_TREE;
|
||||
case SHORT_JUNGLE -> TreeFeatures.JUNGLE_TREE_NO_VINE;
|
||||
case JUNGLE_BUSH -> TreeFeatures.JUNGLE_BUSH;
|
||||
case SWAMP -> TreeFeatures.SWAMP_OAK;
|
||||
case ACACIA -> TreeFeatures.ACACIA;
|
||||
case DARK_OAK -> TreeFeatures.DARK_OAK;
|
||||
case TALL_BIRCH -> TreeFeatures.SUPER_BIRCH_BEES_0002;
|
||||
case RED_MUSHROOM -> TreeFeatures.HUGE_RED_MUSHROOM;
|
||||
case BROWN_MUSHROOM -> TreeFeatures.HUGE_BROWN_MUSHROOM;
|
||||
case WARPED_FUNGUS -> TreeFeatures.WARPED_FUNGUS;
|
||||
case CRIMSON_FUNGUS -> TreeFeatures.CRIMSON_FUNGUS;
|
||||
case CHORUS_PLANT -> EndFeatures.CHORUS_PLANT;
|
||||
case MANGROVE -> TreeFeatures.MANGROVE;
|
||||
case TALL_MANGROVE -> TreeFeatures.TALL_MANGROVE;
|
||||
case CHERRY -> TreeFeatures.CHERRY;
|
||||
case RANDOM ->
|
||||
createTreeFeatureGenerator(TreeGenerator.TreeType.values()[ThreadLocalRandom.current().nextInt(TreeGenerator.TreeType.values().length)]);
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, BlockVector3 position) {
|
||||
ServerLevel world = (ServerLevel) getWorld();
|
||||
ConfiguredFeature<?, ?> generator = Optional.ofNullable(createTreeFeatureGenerator(type))
|
||||
.map(k -> world.registryAccess().registryOrThrow(Registries.CONFIGURED_FEATURE).get(k))
|
||||
.orElse(null);
|
||||
return generator != null && generator.place(
|
||||
world, world.getChunkSource().getGenerator(), random,
|
||||
new BlockPos(position.x(), position.y(), position.z())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockLightLevel(BlockVector3 position) {
|
||||
checkNotNull(position);
|
||||
|
||||
int skyLight = getWorld().light(LightTypes.SKY, position.x(), position.y(), position.z());
|
||||
int groundLight = getWorld().light(LightTypes.BLOCK, position.x(), position.y(), position.z());
|
||||
|
||||
return Math.max(skyLight, groundLight);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeType getBiome(BlockVector3 position) {
|
||||
checkNotNull(position);
|
||||
return BiomeType.REGISTRY.get(
|
||||
getWorld().registry(RegistryTypes.BIOME)
|
||||
.valueKey(getWorld().biome(position.x(), position.y(), position.z()))
|
||||
.asString()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||
checkNotNull(position);
|
||||
checkNotNull(biome);
|
||||
|
||||
getWorld().setBiome(
|
||||
position.x(), position.y(), position.z(),
|
||||
getWorld().registry(RegistryTypes.BIOME).value(
|
||||
ResourceKey.resolve(biome.id())
|
||||
)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropItem(Vector3 position, BaseItemStack item) {
|
||||
checkNotNull(position);
|
||||
checkNotNull(item);
|
||||
|
||||
if (item.getType() == ItemTypes.AIR) {
|
||||
return;
|
||||
}
|
||||
|
||||
Item itemEntity = getWorld().createEntity(
|
||||
EntityTypes.ITEM,
|
||||
new Vector3d(position.x(), position.y(), position.z())
|
||||
);
|
||||
|
||||
itemEntity.item().set(
|
||||
SpongeAdapter.adapt(item).createSnapshot()
|
||||
);
|
||||
getWorld().spawnEntity(itemEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simulateBlockMine(BlockVector3 position) {
|
||||
getWorld().destroyBlock(
|
||||
new Vector3i(position.x(), position.y(), position.z()),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceAt(BlockVector3 position, com.sk89q.worldedit.world.block.BlockState blockState) {
|
||||
return ((net.minecraft.world.level.block.state.BlockState) SpongeAdapter.adapt(blockState))
|
||||
.canSurvive(
|
||||
((LevelReader) getWorld()),
|
||||
new BlockPos(position.x(), position.y(), position.z())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getWorld().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null) {
|
||||
return false;
|
||||
} else if ((o instanceof SpongeWorld other)) {
|
||||
ServerWorld otherWorld = other.worldRef.get();
|
||||
ServerWorld thisWorld = worldRef.get();
|
||||
return otherWorld != null && otherWorld.equals(thisWorld);
|
||||
} else {
|
||||
return o instanceof com.sk89q.worldedit.world.World
|
||||
&& ((com.sk89q.worldedit.world.World) o).getName().equals(getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Entity> getEntities(Region region) {
|
||||
return getWorld()
|
||||
.entityStream(
|
||||
SpongeAdapter.adaptVector3i(region.getMinimumPoint()),
|
||||
SpongeAdapter.adaptVector3i(region.getMaximumPoint()),
|
||||
// We don't need to force load or clone to copy entities
|
||||
StreamOptions.builder()
|
||||
.setCarbonCopy(false)
|
||||
.setLoadingStyle(StreamOptions.LoadingStyle.NONE)
|
||||
.build()
|
||||
)
|
||||
.toStream()
|
||||
.map(ve -> new SpongeEntity(ve.type()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Entity> getEntities() {
|
||||
return getWorld().entities().stream()
|
||||
.map(SpongeEntity::new)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Entity createEntity(Location location, BaseEntity entity) {
|
||||
Optional<EntityType<?>> entityType = Sponge.game().registry(RegistryTypes.ENTITY_TYPE)
|
||||
.findValue(ResourceKey.resolve(entity.getType().id()));
|
||||
if (entityType.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
EntityArchetype.Builder builder = EntityArchetype.builder().type(entityType.get());
|
||||
var nativeTag = entity.getNbt();
|
||||
if (nativeTag != null) {
|
||||
builder.entityData(NbtAdapter.adaptFromWorldEdit(nativeTag));
|
||||
}
|
||||
return builder.build().apply(SpongeAdapter.adapt(location)).map(SpongeEntity::new).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WeatherType getWeather() {
|
||||
return WeatherTypes.get(
|
||||
getWorld().weather().type().key(RegistryTypes.WEATHER_TYPE).asString()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRemainingWeatherDuration() {
|
||||
return getWorld().weather().remainingDuration().ticks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWeather(WeatherType weatherType) {
|
||||
getWorld().setWeather(
|
||||
Sponge.game().registry(RegistryTypes.WEATHER_TYPE).value(
|
||||
ResourceKey.resolve(weatherType.id())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWeather(WeatherType weatherType, long duration) {
|
||||
getWorld().setWeather(
|
||||
Sponge.game().registry(RegistryTypes.WEATHER_TYPE).value(
|
||||
ResourceKey.resolve(weatherType.id())
|
||||
),
|
||||
Ticks.of(duration)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVector3 getSpawnPosition() {
|
||||
return SpongeAdapter.adaptVector3i(getWorld().properties().spawnPosition());
|
||||
}
|
||||
|
||||
}
|
@ -1,485 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.inject.Inject;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.PermissionCondition;
|
||||
import com.sk89q.worldedit.event.platform.CommandEvent;
|
||||
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
|
||||
import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
|
||||
import com.sk89q.worldedit.event.platform.PlatformUnreadyEvent;
|
||||
import com.sk89q.worldedit.event.platform.PlatformsRegisteredEvent;
|
||||
import com.sk89q.worldedit.event.platform.SessionIdleEvent;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.extension.platform.Platform;
|
||||
import com.sk89q.worldedit.extension.platform.PlatformManager;
|
||||
import com.sk89q.worldedit.internal.anvil.ChunkDeleter;
|
||||
import com.sk89q.worldedit.internal.command.CommandUtil;
|
||||
import com.sk89q.worldedit.internal.event.InteractionDebouncer;
|
||||
import com.sk89q.worldedit.sponge.config.SpongeConfiguration;
|
||||
import com.sk89q.worldedit.world.biome.BiomeCategory;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BlockCategory;
|
||||
import com.sk89q.worldedit.world.item.ItemCategory;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bstats.sponge.Metrics;
|
||||
import org.spongepowered.api.ResourceKey;
|
||||
import org.spongepowered.api.Server;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.block.BlockSnapshot;
|
||||
import org.spongepowered.api.block.BlockType;
|
||||
import org.spongepowered.api.block.entity.BlockEntity;
|
||||
import org.spongepowered.api.block.entity.CommandBlock;
|
||||
import org.spongepowered.api.command.Command;
|
||||
import org.spongepowered.api.command.CommandCause;
|
||||
import org.spongepowered.api.command.CommandCompletion;
|
||||
import org.spongepowered.api.command.CommandResult;
|
||||
import org.spongepowered.api.command.parameter.ArgumentReader;
|
||||
import org.spongepowered.api.config.ConfigDir;
|
||||
import org.spongepowered.api.data.type.HandTypes;
|
||||
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
|
||||
import org.spongepowered.api.event.EventContextKeys;
|
||||
import org.spongepowered.api.event.Listener;
|
||||
import org.spongepowered.api.event.action.InteractEvent;
|
||||
import org.spongepowered.api.event.block.InteractBlockEvent;
|
||||
import org.spongepowered.api.event.filter.cause.Root;
|
||||
import org.spongepowered.api.event.item.inventory.InteractItemEvent;
|
||||
import org.spongepowered.api.event.lifecycle.ConstructPluginEvent;
|
||||
import org.spongepowered.api.event.lifecycle.RegisterCommandEvent;
|
||||
import org.spongepowered.api.event.lifecycle.StartedEngineEvent;
|
||||
import org.spongepowered.api.event.lifecycle.StartingEngineEvent;
|
||||
import org.spongepowered.api.event.lifecycle.StoppingEngineEvent;
|
||||
import org.spongepowered.api.event.network.ServerSideConnectionEvent;
|
||||
import org.spongepowered.api.registry.RegistryTypes;
|
||||
import org.spongepowered.api.scheduler.Task;
|
||||
import org.spongepowered.api.world.LocatableBlock;
|
||||
import org.spongepowered.api.world.server.ServerLocation;
|
||||
import org.spongepowered.api.world.server.ServerWorld;
|
||||
import org.spongepowered.math.vector.Vector3d;
|
||||
import org.spongepowered.plugin.PluginContainer;
|
||||
import org.spongepowered.plugin.builtin.jvm.Plugin;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.sk89q.worldedit.internal.anvil.ChunkDeleter.DELCHUNKS_FILE_NAME;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
/**
|
||||
* The Sponge implementation of WorldEdit.
|
||||
*/
|
||||
@Plugin(SpongeWorldEdit.MOD_ID)
|
||||
public class SpongeWorldEdit {
|
||||
|
||||
public static final String MOD_ID = "worldedit";
|
||||
private static final int BSTATS_PLUGIN_ID = 3329;
|
||||
|
||||
private static SpongeWorldEdit inst;
|
||||
|
||||
public static SpongeWorldEdit inst() {
|
||||
return inst;
|
||||
}
|
||||
|
||||
private final Logger logger;
|
||||
private final PluginContainer container;
|
||||
private final SpongeConfiguration config;
|
||||
private final Path workingDir;
|
||||
|
||||
private InteractionDebouncer debouncer;
|
||||
private SpongePermissionsProvider provider;
|
||||
private SpongePlatform platform;
|
||||
|
||||
@Inject
|
||||
public SpongeWorldEdit(Logger logger,
|
||||
PluginContainer container,
|
||||
SpongeConfiguration config,
|
||||
Metrics.Factory metricsFactory,
|
||||
@ConfigDir(sharedRoot = false)
|
||||
Path workingDir) {
|
||||
this.logger = logger;
|
||||
this.container = container;
|
||||
this.config = config;
|
||||
this.workingDir = workingDir;
|
||||
metricsFactory.make(BSTATS_PLUGIN_ID);
|
||||
inst = this;
|
||||
}
|
||||
|
||||
@Listener
|
||||
public void onPluginConstruction(ConstructPluginEvent event) {
|
||||
this.platform = new SpongePlatform(this);
|
||||
debouncer = new InteractionDebouncer(platform);
|
||||
|
||||
WorldEdit.getInstance().getPlatformManager().register(platform);
|
||||
|
||||
this.provider = new SpongePermissionsProvider();
|
||||
|
||||
event.game().eventManager().registerListeners(
|
||||
container,
|
||||
new CUIChannelHandler.RegistrationHandler()
|
||||
);
|
||||
logger.info("WorldEdit for Sponge (version " + getInternalVersion() + ") is loaded");
|
||||
}
|
||||
|
||||
@Listener
|
||||
public void serverStarting(StartingEngineEvent<Server> event) {
|
||||
final Path delChunks = workingDir.resolve(DELCHUNKS_FILE_NAME);
|
||||
if (Files.exists(delChunks)) {
|
||||
ChunkDeleter.runFromFile(delChunks, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Listener
|
||||
public void serverStarted(StartedEngineEvent<Server> event) {
|
||||
event.engine().scheduler().submit(Task.builder()
|
||||
.plugin(container)
|
||||
.interval(30, TimeUnit.SECONDS)
|
||||
.execute(ThreadSafeCache.getInstance())
|
||||
.build());
|
||||
|
||||
event.game().registry(RegistryTypes.BLOCK_TYPE).streamEntries().forEach(blockType -> {
|
||||
String id = blockType.key().asString();
|
||||
if (!com.sk89q.worldedit.world.block.BlockType.REGISTRY.keySet().contains(id)) {
|
||||
com.sk89q.worldedit.world.block.BlockType.REGISTRY.register(id, new com.sk89q.worldedit.world.block.BlockType(
|
||||
id,
|
||||
input -> {
|
||||
BlockType spongeBlockType = Sponge.game().registry(RegistryTypes.BLOCK_TYPE).value(
|
||||
ResourceKey.resolve(input.getBlockType().id())
|
||||
);
|
||||
return SpongeAdapter.adapt(spongeBlockType.defaultState());
|
||||
}
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
event.game().registry(RegistryTypes.ITEM_TYPE).streamEntries().forEach(itemType -> {
|
||||
String id = itemType.key().asString();
|
||||
if (!com.sk89q.worldedit.world.item.ItemType.REGISTRY.keySet().contains(id)) {
|
||||
com.sk89q.worldedit.world.item.ItemType.REGISTRY.register(id, new com.sk89q.worldedit.world.item.ItemType(id));
|
||||
}
|
||||
});
|
||||
|
||||
event.game().registry(RegistryTypes.ENTITY_TYPE).streamEntries().forEach(entityType -> {
|
||||
String id = entityType.key().asString();
|
||||
if (!com.sk89q.worldedit.world.entity.EntityType.REGISTRY.keySet().contains(id)) {
|
||||
com.sk89q.worldedit.world.entity.EntityType.REGISTRY.register(id, new com.sk89q.worldedit.world.entity.EntityType(id));
|
||||
}
|
||||
});
|
||||
|
||||
for (ServerWorld world : event.engine().worldManager().worlds()) {
|
||||
world.registry(RegistryTypes.BIOME).streamEntries().forEach(biomeType -> {
|
||||
String id = biomeType.key().asString();
|
||||
if (!BiomeType.REGISTRY.keySet().contains(id)) {
|
||||
BiomeType.REGISTRY.register(id, new BiomeType(id));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
event.game().registry(RegistryTypes.BLOCK_TYPE).tags().forEach(blockTypeTag -> {
|
||||
String id = blockTypeTag.key().asString();
|
||||
if (!BlockCategory.REGISTRY.keySet().contains(id)) {
|
||||
BlockCategory.REGISTRY.register(id, new BlockCategory(id));
|
||||
}
|
||||
});
|
||||
event.game().registry(RegistryTypes.ITEM_TYPE).tags().forEach(itemTypeTag -> {
|
||||
String id = itemTypeTag.key().asString();
|
||||
if (!ItemCategory.REGISTRY.keySet().contains(id)) {
|
||||
ItemCategory.REGISTRY.register(id, new ItemCategory(id));
|
||||
}
|
||||
});
|
||||
event.game().registry(RegistryTypes.BIOME).tags().forEach(biomeTag -> {
|
||||
String id = biomeTag.key().asString();
|
||||
if (!BiomeCategory.REGISTRY.keySet().contains(id)) {
|
||||
BiomeCategory.REGISTRY.register(id, new BiomeCategory(id, () -> event.game().registry(RegistryTypes.BIOME).taggedValues(biomeTag).stream().map(SpongeAdapter::adapt).collect(Collectors.toSet())));
|
||||
}
|
||||
});
|
||||
|
||||
config.load();
|
||||
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent(platform));
|
||||
}
|
||||
|
||||
@Listener
|
||||
public void serverStopping(StoppingEngineEvent<Server> event) {
|
||||
WorldEdit worldEdit = WorldEdit.getInstance();
|
||||
worldEdit.getSessionManager().unload();
|
||||
WorldEdit.getInstance().getEventBus().post(new PlatformUnreadyEvent(platform));
|
||||
}
|
||||
|
||||
@Listener
|
||||
public void registerCommand(RegisterCommandEvent<Command.Raw> event) {
|
||||
WorldEdit.getInstance().getEventBus().post(new PlatformsRegisteredEvent());
|
||||
PlatformManager manager = WorldEdit.getInstance().getPlatformManager();
|
||||
Platform commandsPlatform = manager.queryCapability(Capability.USER_COMMANDS);
|
||||
if (commandsPlatform != platform || !platform.isHookingEvents()) {
|
||||
// We're not in control of commands/events -- do not register.
|
||||
return;
|
||||
}
|
||||
|
||||
List<org.enginehub.piston.Command> commands = manager.getPlatformCommandManager().getCommandManager()
|
||||
.getAllCommands().toList();
|
||||
for (org.enginehub.piston.Command command : commands) {
|
||||
registerAdaptedCommand(event, command);
|
||||
|
||||
Set<String> perms = command.getCondition().as(PermissionCondition.class)
|
||||
.map(PermissionCondition::getPermissions)
|
||||
.orElseGet(Collections::emptySet);
|
||||
if (!perms.isEmpty()) {
|
||||
perms.forEach(getPermissionsProvider()::registerPermission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String rebuildArguments(String commandLabel, String args) {
|
||||
int plSep = commandLabel.indexOf(':');
|
||||
if (plSep >= 0 && plSep < commandLabel.length() + 1) {
|
||||
commandLabel = commandLabel.substring(plSep + 1);
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder("/").append(commandLabel);
|
||||
|
||||
String[] split = args.split(" ", -1);
|
||||
if (split.length > 0) {
|
||||
sb.append(" ");
|
||||
}
|
||||
return Joiner.on(" ").appendTo(sb, split).toString();
|
||||
}
|
||||
|
||||
private void registerAdaptedCommand(RegisterCommandEvent<Command.Raw> event, org.enginehub.piston.Command command) {
|
||||
CommandAdapter adapter = new CommandAdapter(command) {
|
||||
@Override
|
||||
public CommandResult process(CommandCause cause, ArgumentReader.Mutable arguments) {
|
||||
CommandEvent weEvent = new CommandEvent(SpongeWorldEdit.inst().wrapCommandCause(cause), rebuildArguments(command.getName(), arguments.remaining()).trim());
|
||||
WorldEdit.getInstance().getEventBus().post(weEvent);
|
||||
return weEvent.isCancelled() ? CommandResult.success() : CommandResult.builder().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CommandCompletion> complete(CommandCause cause, ArgumentReader.Mutable arguments) {
|
||||
String args = rebuildArguments(command.getName(), arguments.remaining());
|
||||
CommandSuggestionEvent weEvent = new CommandSuggestionEvent(SpongeWorldEdit.inst().wrapCommandCause(cause), args);
|
||||
WorldEdit.getInstance().getEventBus().post(weEvent);
|
||||
return CommandUtil.fixSuggestions(args, weEvent.getSuggestions())
|
||||
.stream().map(CommandCompletion::of).collect(toList());
|
||||
}
|
||||
};
|
||||
event.register(
|
||||
container, adapter, command.getName(), command.getAliases().toArray(new String[0])
|
||||
);
|
||||
}
|
||||
|
||||
private boolean skipEvents() {
|
||||
return platform == null || !platform.isHookingEvents();
|
||||
}
|
||||
|
||||
private boolean skipInteractionEvent(InteractEvent event) {
|
||||
return skipEvents() || event.context().get(EventContextKeys.USED_HAND).orElse(null) != HandTypes.MAIN_HAND.get();
|
||||
}
|
||||
|
||||
@Listener
|
||||
public void onPlayerInteractItemPrimary(InteractItemEvent.Primary event, @Root ServerPlayer spongePlayer) {
|
||||
if (skipInteractionEvent(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
WorldEdit we = WorldEdit.getInstance();
|
||||
SpongePlayer player = SpongeAdapter.adapt(spongePlayer);
|
||||
|
||||
Optional<Boolean> previousResult = debouncer.getDuplicateInteractionResult(player);
|
||||
if (previousResult.isPresent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean result = we.handleArmSwing(player);
|
||||
debouncer.setLastInteraction(player, result);
|
||||
}
|
||||
|
||||
@Listener
|
||||
public void onPlayerInteractItemSecondary(InteractItemEvent.Secondary event, @Root ServerPlayer spongePlayer) {
|
||||
if (skipInteractionEvent(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
WorldEdit we = WorldEdit.getInstance();
|
||||
SpongePlayer player = SpongeAdapter.adapt(spongePlayer);
|
||||
|
||||
Optional<Boolean> previousResult = debouncer.getDuplicateInteractionResult(player);
|
||||
if (previousResult.isPresent()) {
|
||||
if (previousResult.get()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
boolean result = we.handleRightClick(player);
|
||||
debouncer.setLastInteraction(player, result);
|
||||
|
||||
if (result) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Listener
|
||||
public void onPlayerInteractBlockPrimary(InteractBlockEvent.Primary.Start event, @Root ServerPlayer spongePlayer) {
|
||||
if (skipInteractionEvent(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
WorldEdit we = WorldEdit.getInstance();
|
||||
SpongePlayer player = SpongeAdapter.adapt(spongePlayer);
|
||||
|
||||
BlockSnapshot targetBlock = event.block();
|
||||
Optional<ServerLocation> optLoc = targetBlock.location();
|
||||
|
||||
boolean result = false;
|
||||
if (optLoc.isPresent()) {
|
||||
ServerLocation loc = optLoc.get();
|
||||
com.sk89q.worldedit.util.Location pos = SpongeAdapter.adapt(loc, Vector3d.ZERO);
|
||||
|
||||
result = we.handleBlockLeftClick(player, pos, SpongeAdapter.adapt(event.targetSide()));
|
||||
}
|
||||
|
||||
result = we.handleArmSwing(player) || result;
|
||||
debouncer.setLastInteraction(player, result);
|
||||
|
||||
if (result) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Listener
|
||||
public void onPlayerInteractBlockSecondary(InteractBlockEvent.Secondary event, @Root ServerPlayer spongePlayer) {
|
||||
if (skipInteractionEvent(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
WorldEdit we = WorldEdit.getInstance();
|
||||
SpongePlayer player = SpongeAdapter.adapt(spongePlayer);
|
||||
|
||||
BlockSnapshot targetBlock = event.block();
|
||||
Optional<ServerLocation> optLoc = targetBlock.location();
|
||||
|
||||
boolean result = false;
|
||||
if (optLoc.isPresent()) {
|
||||
ServerLocation loc = optLoc.get();
|
||||
com.sk89q.worldedit.util.Location pos = SpongeAdapter.adapt(loc, Vector3d.ZERO);
|
||||
|
||||
result = we.handleBlockRightClick(player, pos, SpongeAdapter.adapt(event.targetSide()));
|
||||
}
|
||||
|
||||
result = we.handleRightClick(player) || result;
|
||||
debouncer.setLastInteraction(player, result);
|
||||
|
||||
if (result) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Listener
|
||||
public void onPlayerQuit(ServerSideConnectionEvent.Disconnect event) {
|
||||
debouncer.clearInteraction(SpongeAdapter.adapt(event.player()));
|
||||
|
||||
WorldEdit.getInstance().getEventBus()
|
||||
.post(new SessionIdleEvent(new SpongePlayer.SessionKeyImpl(event.player())));
|
||||
}
|
||||
|
||||
public PluginContainer getPluginContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the configuration.
|
||||
*
|
||||
* @return the Sponge configuration
|
||||
*/
|
||||
SpongeConfiguration getConfig() {
|
||||
return this.config;
|
||||
}
|
||||
|
||||
public Actor wrapCommandCause(CommandCause cause) {
|
||||
Object rootCause = cause.root();
|
||||
if (rootCause instanceof ServerPlayer) {
|
||||
return SpongeAdapter.adapt((ServerPlayer) rootCause);
|
||||
}
|
||||
if (rootCause instanceof LocatableBlock locatableBlock) {
|
||||
Optional<? extends BlockEntity> optionalBlockEntity = locatableBlock.world().blockEntity(locatableBlock.blockPosition());
|
||||
if (optionalBlockEntity.isPresent()) {
|
||||
BlockEntity blockEntity = optionalBlockEntity.get();
|
||||
if (blockEntity instanceof CommandBlock commandBlock) {
|
||||
return new SpongeBlockCommandSender(this, commandBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rootCause instanceof Audience) {
|
||||
return new SpongeCommandSender((Audience) rootCause);
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("Cannot wrap " + rootCause.getClass());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the WorldEdit proxy for the platform.
|
||||
*
|
||||
* @return the WorldEdit platform
|
||||
*/
|
||||
public Platform getPlatform() {
|
||||
return this.platform;
|
||||
}
|
||||
|
||||
SpongePlatform getInternalPlatform() {
|
||||
return this.platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the working directory where WorldEdit's files are stored.
|
||||
*
|
||||
* @return the working directory
|
||||
*/
|
||||
public Path getWorkingDir() {
|
||||
return this.workingDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version of the WorldEdit Sponge implementation.
|
||||
*
|
||||
* @return a version string
|
||||
*/
|
||||
String getInternalVersion() {
|
||||
return container.metadata().version().toString();
|
||||
}
|
||||
|
||||
public void setPermissionsProvider(SpongePermissionsProvider provider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
public SpongePermissionsProvider getPermissionsProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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.sponge;
|
||||
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
/**
|
||||
* Caches data that cannot be accessed from another thread safely.
|
||||
*/
|
||||
public class ThreadSafeCache implements Runnable {
|
||||
|
||||
private static final ThreadSafeCache INSTANCE = new ThreadSafeCache();
|
||||
private Set<UUID> onlineIds = new CopyOnWriteArraySet<>();
|
||||
|
||||
/**
|
||||
* Get an concurrent-safe set of UUIDs of online players.
|
||||
*
|
||||
* @return a set of UUIDs
|
||||
*/
|
||||
public Set<UUID> getOnlineIds() {
|
||||
return onlineIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
List<UUID> onlineIds = new ArrayList<>();
|
||||
|
||||
for (ServerPlayer player : Sponge.server().onlinePlayers()) {
|
||||
onlineIds.add(player.uniqueId());
|
||||
}
|
||||
|
||||
this.onlineIds = new CopyOnWriteArraySet<>(onlineIds);
|
||||
}
|
||||
|
||||
public static ThreadSafeCache getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
}
|
@ -1,149 +0,0 @@
|
||||
/*
|
||||
* 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.sponge.config;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.session.SessionManager;
|
||||
import com.sk89q.worldedit.util.report.Unreported;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.spongepowered.configurate.CommentedConfigurationNode;
|
||||
import org.spongepowered.configurate.ConfigurationOptions;
|
||||
import org.spongepowered.configurate.loader.ConfigurationLoader;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
|
||||
public class ConfigurateConfiguration extends LocalConfiguration {
|
||||
|
||||
@Unreported
|
||||
protected final ConfigurationLoader<CommentedConfigurationNode> config;
|
||||
@Unreported
|
||||
protected final Logger logger;
|
||||
|
||||
@Unreported
|
||||
protected CommentedConfigurationNode node;
|
||||
|
||||
public ConfigurateConfiguration(ConfigurationLoader<CommentedConfigurationNode> config, Logger logger) {
|
||||
this.config = config;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
try {
|
||||
ConfigurationOptions options = ConfigurationOptions.defaults();
|
||||
options = options.shouldCopyDefaults(true);
|
||||
|
||||
node = config.load(options);
|
||||
} catch (IOException e) {
|
||||
logger.warn("Error loading WorldEdit configuration", e);
|
||||
}
|
||||
|
||||
profile = node.node("debug").getBoolean(profile);
|
||||
traceUnflushedSessions = node.node("debugging", "trace-unflushed-sessions").getBoolean(traceUnflushedSessions);
|
||||
wandItem = node.node("wand-item").getString(wandItem).toLowerCase(Locale.ROOT);
|
||||
try {
|
||||
wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).id();
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
||||
defaultChangeLimit = Math.max(-1, node.node("limits", "max-blocks-changed", "default").getInt(defaultChangeLimit));
|
||||
maxChangeLimit = Math.max(-1, node.node("limits", "max-blocks-changed", "maximum").getInt(maxChangeLimit));
|
||||
|
||||
defaultVerticalHeight = Math.max(1, node.node("limits", "vertical-height", "default").getInt(defaultVerticalHeight));
|
||||
|
||||
defaultMaxPolygonalPoints = Math.max(-1, node.node("limits", "max-polygonal-points", "default").getInt(defaultMaxPolygonalPoints));
|
||||
maxPolygonalPoints = Math.max(-1, node.node("limits", "max-polygonal-points", "maximum").getInt(maxPolygonalPoints));
|
||||
|
||||
maxRadius = Math.max(-1, node.node("limits", "max-radius").getInt(maxRadius));
|
||||
maxBrushRadius = node.node("limits", "max-brush-radius").getInt(maxBrushRadius);
|
||||
maxSuperPickaxeSize = Math.max(1, node.node("limits", "max-super-pickaxe-size").getInt(maxSuperPickaxeSize));
|
||||
|
||||
butcherDefaultRadius = Math.max(-1, node.node("limits", "butcher-radius", "default").getInt(butcherDefaultRadius));
|
||||
butcherMaxRadius = Math.max(-1, node.node("limits", "butcher-radius", "maximum").getInt(butcherMaxRadius));
|
||||
|
||||
try {
|
||||
disallowedBlocks = new HashSet<>(
|
||||
node.node("limits", "disallowed-blocks").getList(
|
||||
String.class,
|
||||
ImmutableList.copyOf(getDefaultDisallowedBlocks())
|
||||
)
|
||||
);
|
||||
} catch (SerializationException e) {
|
||||
logger.warn("Error loading WorldEdit configuration", e);
|
||||
}
|
||||
try {
|
||||
allowedDataCycleBlocks = new HashSet<>(
|
||||
node.node("limits", "allowed-data-cycle-blocks").getList(String.class, ImmutableList.of())
|
||||
);
|
||||
} catch (SerializationException e) {
|
||||
logger.warn("Error loading WorldEdit configuration", e);
|
||||
}
|
||||
|
||||
registerHelp = node.node("register-help").getBoolean(true);
|
||||
logCommands = node.node("logging", "log-commands").getBoolean(logCommands);
|
||||
logFile = node.node("logging", "file").getString(logFile);
|
||||
logFormat = node.node("logging", "format").getString(logFormat);
|
||||
|
||||
superPickaxeDrop = node.node("super-pickaxe", "drop-items").getBoolean(superPickaxeDrop);
|
||||
superPickaxeManyDrop = node.node("super-pickaxe", "many-drop-items").getBoolean(superPickaxeManyDrop);
|
||||
|
||||
useInventory = node.node("use-inventory", "enable").getBoolean(useInventory);
|
||||
useInventoryOverride = node.node("use-inventory", "allow-override").getBoolean(useInventoryOverride);
|
||||
useInventoryCreativeOverride = node.node("use-inventory", "creative-mode-overrides").getBoolean(useInventoryCreativeOverride);
|
||||
|
||||
navigationWand = node.node("navigation-wand", "item").getString(navigationWand).toLowerCase(Locale.ROOT);
|
||||
try {
|
||||
navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).id();
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
navigationWandMaxDistance = node.node("navigation-wand", "max-distance").getInt(navigationWandMaxDistance);
|
||||
navigationUseGlass = node.node("navigation", "use-glass").getBoolean(navigationUseGlass);
|
||||
|
||||
scriptTimeout = node.node("scripting", "timeout").getInt(scriptTimeout);
|
||||
scriptsDir = node.node("scripting", "dir").getString(scriptsDir);
|
||||
|
||||
saveDir = node.node("saving", "dir").getString(saveDir);
|
||||
|
||||
allowSymlinks = node.node("files", "allow-symbolic-links").getBoolean(false);
|
||||
LocalSession.MAX_HISTORY_SIZE = Math.max(0, node.node("history", "size").getInt(15));
|
||||
SessionManager.EXPIRATION_GRACE = node.node("history", "expiration").getInt(10) * 60 * 1000;
|
||||
|
||||
showHelpInfo = node.node("show-help-on-first-use").getBoolean(true);
|
||||
serverSideCUI = node.node("server-side-cui").getBoolean(true);
|
||||
|
||||
String snapshotsDir = node.node("snapshots", "directory").getString("");
|
||||
boolean experimentalSnapshots = node.node("snapshots", "experimental").getBoolean(false);
|
||||
initializeSnapshotConfiguration(snapshotsDir, experimentalSnapshots);
|
||||
|
||||
String type = node.node("shell-save-type").getString("").trim();
|
||||
shellSaveType = type.isEmpty() ? null : type;
|
||||
|
||||
extendedYLimit = node.node("compat", "extended-y-limit").getBoolean(false);
|
||||
setDefaultLocaleName(node.node("default-locale").getString(defaultLocaleName));
|
||||
|
||||
commandBlockSupport = node.node("command-block-support").getBoolean(false);
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* 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.sponge.config;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.sk89q.worldedit.sponge.SpongeWorldEdit;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.spongepowered.api.config.DefaultConfig;
|
||||
import org.spongepowered.configurate.CommentedConfigurationNode;
|
||||
import org.spongepowered.configurate.loader.ConfigurationLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class SpongeConfiguration extends ConfigurateConfiguration {
|
||||
|
||||
public boolean creativeEnable = false;
|
||||
public boolean cheatMode = false;
|
||||
|
||||
@Inject
|
||||
public SpongeConfiguration(@DefaultConfig(sharedRoot = false)
|
||||
ConfigurationLoader<CommentedConfigurationNode> config,
|
||||
Logger logger) {
|
||||
super(config, logger);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
super.load();
|
||||
|
||||
creativeEnable = node.node("use-in-creative").getBoolean(false);
|
||||
cheatMode = node.node("cheat-mode").getBoolean(false);
|
||||
|
||||
try {
|
||||
config.save(node);
|
||||
} catch (IOException e) {
|
||||
logger.warn("Error loading WorldEdit configuration", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getWorkingDirectoryPath() {
|
||||
return SpongeWorldEdit.inst().getWorkingDir();
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* 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.sponge.internal;
|
||||
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public interface ExtendedChunk {
|
||||
/**
|
||||
* {@link LevelChunk#setBlockState(BlockPos, BlockState, boolean)} with the extra
|
||||
* {@link SideEffect#UPDATE} flag.
|
||||
*
|
||||
* @param pos the position to set
|
||||
* @param state the state to set
|
||||
* @param moved I honestly have no idea and can't be bothered to investigate, we pass {@code
|
||||
* false}
|
||||
* @param update the update flag, see side-effect for details
|
||||
* @return the old block state, or {@code null} if unchanged
|
||||
*/
|
||||
@Nullable
|
||||
BlockState setBlockState(BlockPos pos, BlockState state, boolean moved, boolean update);
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
* 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.sponge.internal;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import org.spongepowered.api.util.locale.LocaleSource;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class LocaleResolver {
|
||||
public static Locale resolveLocale(Audience audience) {
|
||||
if (audience instanceof LocaleSource) {
|
||||
return ((LocaleSource) audience).locale();
|
||||
}
|
||||
return WorldEdit.getInstance().getConfiguration().defaultLocale;
|
||||
}
|
||||
}
|
@ -1,272 +0,0 @@
|
||||
/*
|
||||
* 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.sponge.internal;
|
||||
|
||||
import net.minecraft.nbt.ByteArrayTag;
|
||||
import net.minecraft.nbt.ByteTag;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.DoubleTag;
|
||||
import net.minecraft.nbt.FloatTag;
|
||||
import net.minecraft.nbt.IntArrayTag;
|
||||
import net.minecraft.nbt.IntTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.LongArrayTag;
|
||||
import net.minecraft.nbt.LongTag;
|
||||
import net.minecraft.nbt.ShortTag;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import org.enginehub.linbus.tree.LinByteArrayTag;
|
||||
import org.enginehub.linbus.tree.LinByteTag;
|
||||
import org.enginehub.linbus.tree.LinCompoundTag;
|
||||
import org.enginehub.linbus.tree.LinDoubleTag;
|
||||
import org.enginehub.linbus.tree.LinFloatTag;
|
||||
import org.enginehub.linbus.tree.LinIntArrayTag;
|
||||
import org.enginehub.linbus.tree.LinIntTag;
|
||||
import org.enginehub.linbus.tree.LinListTag;
|
||||
import org.enginehub.linbus.tree.LinLongArrayTag;
|
||||
import org.enginehub.linbus.tree.LinLongTag;
|
||||
import org.enginehub.linbus.tree.LinShortTag;
|
||||
import org.enginehub.linbus.tree.LinStringTag;
|
||||
import org.enginehub.linbus.tree.LinTag;
|
||||
import org.enginehub.linbus.tree.LinTagType;
|
||||
import org.spongepowered.api.data.persistence.DataContainer;
|
||||
import org.spongepowered.api.data.persistence.DataQuery;
|
||||
import org.spongepowered.api.data.persistence.DataSerializable;
|
||||
import org.spongepowered.api.data.persistence.DataView;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class NbtAdapter {
|
||||
/**
|
||||
* A separator to introduce errors if there is something to be separated. We should only see
|
||||
* single-part keys.
|
||||
*/
|
||||
private static final String BREAKING_SEPARATOR = "if you see this, something is wrong";
|
||||
|
||||
public static LinCompoundTag adaptToWorldEdit(DataView view) {
|
||||
LinCompoundTag.Builder builder = LinCompoundTag.builder();
|
||||
for (Map.Entry<DataQuery, Object> entry : view.values(false).entrySet()) {
|
||||
builder.put(
|
||||
entry.getKey().asString(BREAKING_SEPARATOR),
|
||||
adaptUnknownToWorldEdit(entry.getValue())
|
||||
);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static LinTag<?> adaptUnknownToWorldEdit(Object object) {
|
||||
if (object instanceof DataView) {
|
||||
return adaptToWorldEdit((DataView) object);
|
||||
}
|
||||
if (object instanceof Boolean) {
|
||||
return LinByteTag.of((byte) ((Boolean) object ? 1 : 0));
|
||||
}
|
||||
if (object instanceof Byte) {
|
||||
return LinByteTag.of((Byte) object);
|
||||
}
|
||||
if (object instanceof Short) {
|
||||
return LinShortTag.of(((Short) object));
|
||||
}
|
||||
if (object instanceof Integer) {
|
||||
return LinIntTag.of(((Integer) object));
|
||||
}
|
||||
if (object instanceof Long) {
|
||||
return LinLongTag.of(((Long) object));
|
||||
}
|
||||
if (object instanceof Float) {
|
||||
return LinFloatTag.of(((Float) object));
|
||||
}
|
||||
if (object instanceof Double) {
|
||||
return LinDoubleTag.of(((Double) object));
|
||||
}
|
||||
if (object instanceof String) {
|
||||
return LinStringTag.of((String) object);
|
||||
}
|
||||
if (object instanceof byte[]) {
|
||||
return LinByteArrayTag.of(((byte[]) object));
|
||||
}
|
||||
if (object instanceof Byte[] array) {
|
||||
byte[] copy = new byte[array.length];
|
||||
for (int i = 0; i < copy.length; i++) {
|
||||
copy[i] = array[i];
|
||||
}
|
||||
return LinByteArrayTag.of(copy);
|
||||
}
|
||||
if (object instanceof int[]) {
|
||||
return LinIntArrayTag.of(((int[]) object));
|
||||
}
|
||||
if (object instanceof Integer[] array) {
|
||||
int[] copy = new int[array.length];
|
||||
for (int i = 0; i < copy.length; i++) {
|
||||
copy[i] = array[i];
|
||||
}
|
||||
return LinIntArrayTag.of(copy);
|
||||
}
|
||||
if (object instanceof long[]) {
|
||||
return LinLongArrayTag.of(((long[]) object));
|
||||
}
|
||||
if (object instanceof Long[] array) {
|
||||
long[] copy = new long[array.length];
|
||||
for (int i = 0; i < copy.length; i++) {
|
||||
copy[i] = array[i];
|
||||
}
|
||||
return LinLongArrayTag.of(copy);
|
||||
}
|
||||
if (object instanceof List<?> objects) {
|
||||
if (objects.isEmpty()) {
|
||||
return LinListTag.empty(LinTagType.endTag());
|
||||
}
|
||||
LinTag<?> first = adaptUnknownToWorldEdit(objects.get(0));
|
||||
@SuppressWarnings("unchecked")
|
||||
LinListTag.Builder<LinTag<?>> builder = LinListTag.builder((LinTagType<LinTag<?>>) first.type());
|
||||
builder.add(first);
|
||||
for (int i = 1; i < objects.size(); i++) {
|
||||
Object value = objects.get(i);
|
||||
builder.add(adaptUnknownToWorldEdit(value));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
if (object instanceof Map) {
|
||||
LinCompoundTag.Builder builder = LinCompoundTag.builder();
|
||||
for (Map.Entry<?, ?> entry : ((Map<?, ?>) object).entrySet()) {
|
||||
String key = entry.getKey() instanceof DataQuery
|
||||
? ((DataQuery) entry.getKey()).asString(BREAKING_SEPARATOR)
|
||||
: entry.getKey().toString();
|
||||
builder.put(key, adaptUnknownToWorldEdit(entry.getValue()));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
if (object instanceof DataSerializable) {
|
||||
return adaptToWorldEdit(((DataSerializable) object).toContainer());
|
||||
}
|
||||
throw new UnsupportedOperationException("Unable to translate into NBT: " + object.getClass());
|
||||
}
|
||||
|
||||
public static DataContainer adaptFromWorldEdit(LinCompoundTag tag) {
|
||||
// copy to container, no cloning used because it's unlikely to leak
|
||||
// and it's cheaper this way
|
||||
DataContainer container = DataContainer.createNew(DataView.SafetyMode.NO_DATA_CLONED);
|
||||
for (var entry : tag.value().entrySet()) {
|
||||
container.set(DataQuery.of(entry.getKey()), adaptTagFromWorldEdit(entry.getValue()));
|
||||
}
|
||||
return container;
|
||||
}
|
||||
|
||||
private static Object adaptTagFromWorldEdit(LinTag<?> value) {
|
||||
if (value instanceof LinListTag<?> listTag) {
|
||||
return listTag.value().stream()
|
||||
.map(NbtAdapter::adaptTagFromWorldEdit)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
if (value instanceof LinCompoundTag compoundTag) {
|
||||
return adaptFromWorldEdit(compoundTag);
|
||||
}
|
||||
// everything else is raw JDK types, so we can use it directly
|
||||
return value.value();
|
||||
}
|
||||
|
||||
public static Tag adaptNMSToWorldEdit(LinTag<?> tag) {
|
||||
if (tag instanceof LinIntArrayTag intArrayTag) {
|
||||
return adaptNMSToWorldEdit(intArrayTag);
|
||||
} else if (tag instanceof LinListTag<?> listTag) {
|
||||
return adaptNMSToWorldEdit(listTag);
|
||||
} else if (tag instanceof LinLongTag longTag) {
|
||||
return adaptNMSToWorldEdit(longTag);
|
||||
} else if (tag instanceof LinLongArrayTag longArrayTag) {
|
||||
return adaptNMSToWorldEdit(longArrayTag);
|
||||
} else if (tag instanceof LinStringTag stringTag) {
|
||||
return adaptNMSToWorldEdit(stringTag);
|
||||
} else if (tag instanceof LinIntTag intTag) {
|
||||
return adaptNMSToWorldEdit(intTag);
|
||||
} else if (tag instanceof LinByteTag byteTag) {
|
||||
return adaptNMSToWorldEdit(byteTag);
|
||||
} else if (tag instanceof LinByteArrayTag byteArrayTag) {
|
||||
return adaptNMSToWorldEdit(byteArrayTag);
|
||||
} else if (tag instanceof LinCompoundTag compoundTag) {
|
||||
return adaptNMSToWorldEdit(compoundTag);
|
||||
} else if (tag instanceof LinFloatTag floatTag) {
|
||||
return adaptNMSToWorldEdit(floatTag);
|
||||
} else if (tag instanceof LinShortTag shortTag) {
|
||||
return adaptNMSToWorldEdit(shortTag);
|
||||
} else if (tag instanceof LinDoubleTag doubleTag) {
|
||||
return adaptNMSToWorldEdit(doubleTag);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Can't convert tag of type " + tag.getClass().getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
public static IntArrayTag adaptNMSToWorldEdit(LinIntArrayTag tag) {
|
||||
return new IntArrayTag(tag.value());
|
||||
}
|
||||
|
||||
public static ListTag adaptNMSToWorldEdit(LinListTag<?> tag) {
|
||||
ListTag list = new ListTag();
|
||||
for (LinTag<?> child : tag.value()) {
|
||||
list.add(adaptNMSToWorldEdit(child));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static LongTag adaptNMSToWorldEdit(LinLongTag tag) {
|
||||
return LongTag.valueOf(tag.valueAsLong());
|
||||
}
|
||||
|
||||
public static LongArrayTag adaptNMSToWorldEdit(LinLongArrayTag tag) {
|
||||
return new LongArrayTag(tag.value());
|
||||
}
|
||||
|
||||
public static StringTag adaptNMSToWorldEdit(LinStringTag tag) {
|
||||
return StringTag.valueOf(tag.value());
|
||||
}
|
||||
|
||||
public static IntTag adaptNMSToWorldEdit(LinIntTag tag) {
|
||||
return IntTag.valueOf(tag.valueAsInt());
|
||||
}
|
||||
|
||||
public static ByteTag adaptNMSToWorldEdit(LinByteTag tag) {
|
||||
return ByteTag.valueOf(tag.valueAsByte());
|
||||
}
|
||||
|
||||
public static ByteArrayTag adaptNMSToWorldEdit(LinByteArrayTag tag) {
|
||||
return new ByteArrayTag(tag.value());
|
||||
}
|
||||
|
||||
public static CompoundTag adaptNMSToWorldEdit(LinCompoundTag tag) {
|
||||
CompoundTag compound = new CompoundTag();
|
||||
for (var child : tag.value().entrySet()) {
|
||||
compound.put(child.getKey(), adaptNMSToWorldEdit(child.getValue()));
|
||||
}
|
||||
return compound;
|
||||
}
|
||||
|
||||
public static FloatTag adaptNMSToWorldEdit(LinFloatTag tag) {
|
||||
return FloatTag.valueOf(tag.valueAsFloat());
|
||||
}
|
||||
|
||||
public static ShortTag adaptNMSToWorldEdit(LinShortTag tag) {
|
||||
return ShortTag.valueOf(tag.valueAsShort());
|
||||
}
|
||||
|
||||
public static DoubleTag adaptNMSToWorldEdit(LinDoubleTag tag) {
|
||||
return DoubleTag.valueOf(tag.valueAsDouble());
|
||||
}
|
||||
}
|
@ -1,210 +0,0 @@
|
||||
/*
|
||||
* 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.sponge.internal;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.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.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import net.minecraft.util.StringRepresentable;
|
||||
import org.spongepowered.api.ResourceKey;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.registry.RegistryTypes;
|
||||
import org.spongepowered.api.state.StateProperty;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Raw, un-cached transformations.
|
||||
*/
|
||||
public class SpongeTransmogrifier {
|
||||
|
||||
private static final LoadingCache<StateProperty<?>, Property<?>> PROPERTY_CACHE = CacheBuilder.newBuilder().build(new CacheLoader<>() {
|
||||
@Override
|
||||
public Property<?> load(StateProperty<?> property) {
|
||||
net.minecraft.world.level.block.state.properties.Property<?> nativeProperty =
|
||||
(net.minecraft.world.level.block.state.properties.Property<?>) property;
|
||||
String propertyName = nativeProperty.getName();
|
||||
if (nativeProperty instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) {
|
||||
return new BooleanProperty(propertyName,
|
||||
ImmutableList.copyOf(((net.minecraft.world.level.block.state.properties.BooleanProperty) nativeProperty).getPossibleValues()));
|
||||
}
|
||||
if (nativeProperty instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) {
|
||||
return new IntegerProperty(propertyName,
|
||||
ImmutableList.copyOf(((net.minecraft.world.level.block.state.properties.IntegerProperty) nativeProperty).getPossibleValues()));
|
||||
}
|
||||
if (isDirectionProperty(nativeProperty)) {
|
||||
return new DirectionalProperty(propertyName,
|
||||
((net.minecraft.world.level.block.state.properties.EnumProperty<?>) nativeProperty).getPossibleValues().stream()
|
||||
.map(x -> adaptDirection((net.minecraft.core.Direction) x))
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
if (nativeProperty instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
|
||||
return new EnumProperty(propertyName,
|
||||
((net.minecraft.world.level.block.state.properties.EnumProperty<?>) nativeProperty).getPossibleValues().stream()
|
||||
.map(StringRepresentable::getSerializedName)
|
||||
.toList());
|
||||
}
|
||||
throw new IllegalStateException("Unknown property type");
|
||||
}
|
||||
});
|
||||
|
||||
public static Property<?> transmogToWorldEditProperty(StateProperty<?> property) {
|
||||
return PROPERTY_CACHE.getUnchecked(property);
|
||||
}
|
||||
|
||||
private static Map<Property<?>, Object> transmogToWorldEditProperties(
|
||||
BlockType block,
|
||||
net.minecraft.world.level.block.state.BlockState blockState
|
||||
) {
|
||||
Map<Property<?>, Object> properties = new TreeMap<>(Comparator.comparing(Property::getName));
|
||||
for (net.minecraft.world.level.block.state.properties.Property<?> nativeProperty: blockState.getProperties()) {
|
||||
Object value = blockState.getValue(nativeProperty);
|
||||
if (isDirectionProperty(nativeProperty)) {
|
||||
net.minecraft.core.Direction nativeDirectionValue = (net.minecraft.core.Direction) value;
|
||||
value = adaptDirection(nativeDirectionValue);
|
||||
} else if (nativeProperty instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
|
||||
value = ((StringRepresentable) value).getSerializedName();
|
||||
}
|
||||
properties.put(block.getProperty(nativeProperty.getName()), value);
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
private static boolean isDirectionProperty(net.minecraft.world.level.block.state.properties.Property<?> property) {
|
||||
return property instanceof net.minecraft.world.level.block.state.properties.EnumProperty
|
||||
&& property.getValueClass().isAssignableFrom(net.minecraft.core.Direction.class);
|
||||
}
|
||||
|
||||
private static Direction adaptDirection(net.minecraft.core.Direction direction) {
|
||||
switch (direction) {
|
||||
case UP:
|
||||
return Direction.UP;
|
||||
case DOWN:
|
||||
return Direction.DOWN;
|
||||
case EAST:
|
||||
return Direction.EAST;
|
||||
case WEST:
|
||||
return Direction.WEST;
|
||||
case NORTH:
|
||||
return Direction.NORTH;
|
||||
case SOUTH:
|
||||
return Direction.SOUTH;
|
||||
default:
|
||||
throw new AssertionError("New direction added: " + direction);
|
||||
}
|
||||
}
|
||||
|
||||
private static net.minecraft.core.Direction adaptDirection(Direction direction) {
|
||||
switch (direction) {
|
||||
case UP:
|
||||
return net.minecraft.core.Direction.UP;
|
||||
case DOWN:
|
||||
return net.minecraft.core.Direction.DOWN;
|
||||
case EAST:
|
||||
return net.minecraft.core.Direction.EAST;
|
||||
case WEST:
|
||||
return net.minecraft.core.Direction.WEST;
|
||||
case NORTH:
|
||||
return net.minecraft.core.Direction.NORTH;
|
||||
case SOUTH:
|
||||
return net.minecraft.core.Direction.SOUTH;
|
||||
default:
|
||||
throw new AssertionError("New direction added: " + direction);
|
||||
}
|
||||
}
|
||||
|
||||
private static net.minecraft.world.level.block.state.properties.Property<?> findPropertyByName(
|
||||
net.minecraft.world.level.block.state.BlockState blockState,
|
||||
String propertyName
|
||||
) {
|
||||
for (net.minecraft.world.level.block.state.properties.Property<?> property: blockState.getProperties()) {
|
||||
if (property.getName().equals(propertyName)) {
|
||||
return property;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Missing property in " + blockState.getBlock() + ": " + propertyName);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private static org.spongepowered.api.block.BlockState transmogToMinecraftProperties(
|
||||
org.spongepowered.api.block.BlockState blockState,
|
||||
Map<Property<?>, Object> states
|
||||
) {
|
||||
net.minecraft.world.level.block.state.BlockState nativeBlockState =
|
||||
(net.minecraft.world.level.block.state.BlockState) blockState;
|
||||
for (Map.Entry<Property<?>, Object> stateEntry: states.entrySet()) {
|
||||
Property<?> property = stateEntry.getKey();
|
||||
Object value = stateEntry.getValue();
|
||||
net.minecraft.world.level.block.state.properties.Property<?> nativeProperty =
|
||||
findPropertyByName(nativeBlockState, property.getName());
|
||||
Comparable<?> nativeValue;
|
||||
if (property instanceof DirectionalProperty) {
|
||||
Direction directionValue = (Direction) value;
|
||||
nativeValue = adaptDirection(directionValue);
|
||||
} else if (property instanceof EnumProperty) {
|
||||
String valueName = (String) value;
|
||||
Optional<? extends Comparable<?>> nativeValueOpt = nativeProperty.getValue(valueName);
|
||||
if (nativeValueOpt.isEmpty()) {
|
||||
throw new IllegalStateException("Failed to parse " + valueName + " into " + property.getName());
|
||||
}
|
||||
nativeValue = nativeValueOpt.get();
|
||||
} else {
|
||||
nativeValue = (Comparable<?>) value;
|
||||
}
|
||||
nativeBlockState = nativeBlockState.setValue(
|
||||
(net.minecraft.world.level.block.state.properties.Property) nativeProperty, (Comparable) nativeValue);
|
||||
}
|
||||
|
||||
return (org.spongepowered.api.block.BlockState) nativeBlockState;
|
||||
}
|
||||
|
||||
public static org.spongepowered.api.block.BlockState transmogToMinecraft(BlockState blockState) {
|
||||
org.spongepowered.api.block.BlockType mcBlock = Sponge.game().registry(RegistryTypes.BLOCK_TYPE)
|
||||
.value(ResourceKey.resolve(blockState.getBlockType().id()));
|
||||
org.spongepowered.api.block.BlockState newState = mcBlock.defaultState();
|
||||
Map<Property<?>, Object> states = blockState.getStates();
|
||||
return transmogToMinecraftProperties(newState, states);
|
||||
}
|
||||
|
||||
public static BlockState transmogToWorldEdit(org.spongepowered.api.block.BlockState blockState) {
|
||||
BlockType blockType = BlockType.REGISTRY.get(
|
||||
blockState.type().key(RegistryTypes.BLOCK_TYPE).asString()
|
||||
);
|
||||
return blockType.getState(transmogToWorldEditProperties(blockType,
|
||||
(net.minecraft.world.level.block.state.BlockState) blockState));
|
||||
}
|
||||
|
||||
private SpongeTransmogrifier() {
|
||||
}
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
/*
|
||||
* 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.sponge.internal;
|
||||
|
||||
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
|
||||
import com.sk89q.worldedit.sponge.SpongeAdapter;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.world.storage.ChunkStore;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.FullChunkStatus;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import org.enginehub.linbus.tree.LinCompoundTag;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Objects;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class SpongeWorldNativeAccess implements WorldNativeAccess<LevelChunk, BlockState, BlockPos> {
|
||||
private static final int UPDATE = 1;
|
||||
private static final int NOTIFY = 2;
|
||||
|
||||
private final WeakReference<ServerLevel> world;
|
||||
private SideEffectSet sideEffectSet;
|
||||
|
||||
public SpongeWorldNativeAccess(WeakReference<ServerLevel> world) {
|
||||
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 BlockState toNative(com.sk89q.worldedit.world.block.BlockState state) {
|
||||
return (BlockState) SpongeAdapter.adapt(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(LevelChunk chunk, BlockPos position) {
|
||||
return chunk.getBlockState(position);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockState setBlockState(LevelChunk chunk, BlockPos position, BlockState state) {
|
||||
if (chunk instanceof ExtendedChunk) {
|
||||
return ((ExtendedChunk) chunk).setBlockState(
|
||||
position, state, false, sideEffectSet.shouldApply(SideEffect.UPDATE)
|
||||
);
|
||||
}
|
||||
return chunk.setBlockState(position, state, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getValidBlockForPosition(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(BlockPos position, LinCompoundTag tag) {
|
||||
CompoundTag nativeTag = NbtAdapter.adaptNMSToWorldEdit(tag);
|
||||
BlockEntity tileEntity = getWorld().getChunk(position).getBlockEntity(position);
|
||||
if (tileEntity == null) {
|
||||
return false;
|
||||
}
|
||||
tileEntity.setLevel(getWorld());
|
||||
tileEntity.load(nativeTag);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyBlockUpdate(LevelChunk chunk, BlockPos position, BlockState oldState, BlockState newState) {
|
||||
if (chunk.getSections()[position.getY() >> ChunkStore.CHUNK_SHIFTS] != null) { // TODO 1.17 - world.get().getSectionIndex(position.getY())
|
||||
getWorld().sendBlockUpdated(position, oldState, newState, UPDATE | NOTIFY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkTicking(LevelChunk chunk) {
|
||||
return chunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markBlockChanged(LevelChunk chunk, BlockPos position) {
|
||||
if (chunk.getSections()[position.getY() >> ChunkStore.CHUNK_SHIFTS] != null) { // TODO 1.17 - world.getSectionIndex(position.getY())
|
||||
getWorld().getChunkSource().blockChanged(position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyNeighbors(BlockPos pos, BlockState oldState, BlockState newState) {
|
||||
getWorld().updateNeighborsAt(pos, oldState.getBlock());
|
||||
if (newState.hasAnalogOutputSignal()) {
|
||||
getWorld().updateNeighbourForOutputSignal(pos, newState.getBlock());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBlock(BlockPos pos, BlockState oldState, BlockState newState) {
|
||||
ServerLevel world = getWorld();
|
||||
newState.onPlace(world, pos, oldState, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNeighbors(BlockPos pos, BlockState oldState, BlockState newState, int recursionLimit) {
|
||||
ServerLevel world = getWorld();
|
||||
oldState.updateNeighbourShapes(world, pos, NOTIFY, recursionLimit);
|
||||
newState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit);
|
||||
newState.updateNeighbourShapes(world, pos, NOTIFY, recursionLimit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockStateChange(BlockPos pos, BlockState oldState, BlockState newState) {
|
||||
getWorld().onBlockStateChange(pos, oldState, newState);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user