Merge branch 'refs/heads/version/7.0.x'

# Conflicts:
#	buildSrc/src/main/kotlin/GradleExtras.kt
#	buildSrc/src/main/kotlin/LibsConfig.kt
#	buildSrc/src/main/kotlin/PlatformConfig.kt
#	gradle.properties
#	worldguard-libs/bukkit/build.gradle.kts
This commit is contained in:
Joo200 2024-09-16 20:08:34 +02:00
commit ab48a66237
48 changed files with 965 additions and 589 deletions

View File

@ -1,8 +0,0 @@
language: java
dist: trusty
jdk:
- oraclejdk11
notifications:
email: false
before_install: chmod +x gradlew
script: ./gradlew build -S

View File

@ -1,5 +1,21 @@
# Changelog
## 7.0.12
* Fix a change in the default behavior of explosion flag handling.
## 7.0.11
* Add support for MC 1.21.
* Add wind-charge-burst flag which is checked along with `use` (for the interaction) or `pvp` (for the knockback).
* Add breeze-charge-explosion flag for breeze charges (i.e. from the mob, not player wind charges).
* Add moisture-change flag and config options.
* Fix an error if a player logged in to an unloaded world.
* Fix chest boat usage always being counted as ride.
* Consider potions thrown by mobs as mob-damage.
* Workaround spigot no longer sending block change events when a book is placed on a lectern.
* Improve accuracy of target blocks in blacklist/build-perms events.
## 7.0.10
* Add support for MC 1.20.5 and 1.20.6, drop support for other 1.20 versions

View File

@ -1,28 +1,28 @@
plugins {
`kotlin-dsl`
kotlin("jvm") version embeddedKotlinVersion
}
repositories {
mavenCentral()
gradlePluginPortal()
}
dependencies {
implementation(gradleApi())
implementation("gradle.plugin.org.cadixdev.gradle:licenser:0.6.1")
implementation("org.ajoberstar.grgit:grgit-gradle:5.2.2")
implementation("com.github.johnrengelman:shadow:8.1.1")
implementation("org.jfrog.buildinfo:build-info-extractor-gradle:5.2.0")
implementation(libs.licenser)
implementation(libs.grgit)
implementation(libs.shadow)
implementation(libs.jfrog.buildinfo)
implementation(libs.gson)
constraints {
val asmVersion = "[9.7,)"
val asmVersion = "[${libs.versions.minimumAsm.get()},)"
implementation("org.ow2.asm:asm:$asmVersion") {
because("Need Java 21 support in shadow")
}
implementation("org.ow2.asm:asm-commons:$asmVersion") {
because("Need Java 21 support in shadow")
}
implementation("org.vafer:jdependency:[2.10,)") {
implementation("org.vafer:jdependency:[${libs.versions.minimumJdependency.get()},)") {
because("Need Java 21 support in shadow")
}
}

View File

@ -0,0 +1,9 @@
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
rootProject.name = "build-logic"

View File

@ -0,0 +1,32 @@
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
}

View File

@ -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")
}
}

View File

@ -0,0 +1,65 @@
import buildlogic.getLibrary
import buildlogic.stringyLibs
plugins {
id("eclipse")
id("idea")
id("checkstyle")
id("buildlogic.common")
}
tasks
.withType<JavaCompile>()
.matching { it.name == "compileJava" || it.name == "compileTestJava" }
.configureEach {
val disabledLint = listOf(
"processing", "path", "fallthrough", "serial", "overloads",
)
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 = "10.16.0"
}
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"))
"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()
}
tasks.named("check").configure {
dependsOn("checkstyleMain", "checkstyleTest")
}

View File

@ -0,0 +1,69 @@
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 {
mavenCentral()
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
}
}
}

View File

@ -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()
}
}
}
}
}

View File

@ -0,0 +1,179 @@
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}.worldguard-libs"
val relocations = mapOf(
"org.enginehub.squirrelid" to "com.sk89q.worldguard.util.profile",
)
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, 21)
}
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, 21)
}
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(":worldguard-libs:core")) {
evaluationDependsOn(":worldguard-libs:core")
configurations["shade"].shouldResolveConsistentlyWith(project(":worldguard-libs:core").configurations["shade"])
}

View File

@ -0,0 +1,39 @@
plugins {
id("com.github.johnrengelman.shadow")
id("buildlogic.core-and-platform")
}
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
archiveClassifier.set("dist")
dependencies {
include(project(":worldguard-libs:core"))
include(project(":worldguard-core"))
relocate("org.flywaydb", "com.sk89q.worldguard.internal.flywaydb") {
include(dependency("org.flywaydb:flyway-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 version = project(":worldguard-core").version
inputs.property("version", version)
val attributes = mutableMapOf(
"Implementation-Version" to version,
"WorldGuard-Version" to version,
)
manifest.attributes(attributes)
}
}

View File

@ -0,0 +1,24 @@
package buildlogic
import org.gradle.api.Project
import org.gradle.api.artifacts.MinimalExternalModuleDependency
import org.gradle.api.artifacts.VersionCatalog
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.api.artifacts.VersionConstraint
import org.gradle.api.plugins.ExtraPropertiesExtension
import org.gradle.api.provider.Provider
import org.gradle.kotlin.dsl.getByType
val Project.ext: ExtraPropertiesExtension
get() = extensions.getByType()
val Project.stringyLibs: VersionCatalog
get() = extensions.getByType<VersionCatalogsExtension>().named("libs")
fun VersionCatalog.getLibrary(name: String): Provider<MinimalExternalModuleDependency> = findLibrary(name).orElseThrow {
error("Library $name not found in version catalog")
}
fun VersionCatalog.getVersion(name: String): VersionConstraint = findVersion(name).orElseThrow {
error("Version $name not found in version catalog")
}

View File

@ -1,23 +1,14 @@
import org.ajoberstar.grgit.Grgit
logger.lifecycle("""
*******************************************
You are building WorldGuard!
If you encounter trouble:
1) Try running 'build' in a separate Gradle run
2) Use gradlew and not gradle
3) If you still need help, ask on Discord! https://discord.gg/enginehub
Output files will be in [subproject]/build/libs
*******************************************
""")
applyRootArtifactoryConfig()
plugins {
id("buildlogic.common")
id("buildlogic.artifactory-root")
}
if (!project.hasProperty("gitCommitHash")) {
apply(plugin = "org.ajoberstar.grgit")
ext["gitCommitHash"] = try {
Grgit.open(mapOf("currentDir" to project.rootDir))?.head()?.abbreviatedId
extensions.getByName<Grgit>("grgit").head()?.abbreviatedId
} catch (e: Exception) {
logger.warn("Error getting commit hash", e)

View File

@ -1,40 +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() {
tasks.named<ArtifactoryTask>("artifactoryPublish") {
publications("maven")
}
}

View File

@ -1,38 +0,0 @@
import org.cadixdev.gradle.licenser.LicenseExtension
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.repositories
import org.gradle.kotlin.dsl.the
fun Project.applyCommonConfiguration() {
group = rootProject.group
version = rootProject.version
repositories {
mavenCentral()
maven { url = uri("https://maven.enginehub.org/repo/") }
maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots/") }
}
configurations.all {
resolutionStrategy {
cacheChangingModulesFor(5, "MINUTES")
}
}
plugins.withId("java") {
the<JavaPluginExtension>().toolchain {
languageVersion.set(JavaLanguageVersion.of(21))
}
}
apply(plugin = "org.cadixdev.licenser")
configure<LicenseExtension> {
header(rootProject.file("HEADER.txt"))
include("**/*.java")
include("**/*.kt")
}
}

View File

@ -1,12 +0,0 @@
import org.gradle.api.Project
import org.gradle.api.plugins.ExtraPropertiesExtension
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.the
val Project.ext: ExtraPropertiesExtension
get() = extensions.getByType()
val Project.sourceSets: SourceSetContainer
get() = the<JavaPluginExtension>().sourceSets

View File

@ -1,187 +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.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}.worldguard-libs"
val relocations = mapOf(
"org.enginehub.squirrelid" to "com.sk89q.worldguard.util.profile"
)
tasks.register<ShadowJar>("jar") {
configurations = listOf(project.configurations["shade"])
archiveClassifier.set("")
dependencies {
exclude(dependency("com.google.code.findbugs:jsr305"))
}
relocations.forEach { (from, to) ->
relocate(from, to)
}
}
val altConfigFiles = { artifactType: String ->
val deps = configurations["shade"].incoming.dependencies
.filterIsInstance<ModuleDependency>()
.map { it.copy() }
.map { dependency ->
dependency.artifact {
name = dependency.name
type = artifactType
extension = "jar"
classifier = artifactType
}
dependency
}
files(configurations.detachedConfiguration(*deps.toTypedArray())
.resolvedConfiguration.lenientConfiguration.artifacts
.filter { it.classifier == artifactType }
.map { zipTree(it.file) })
}
tasks.register<Jar>("sourcesJar") {
from({
altConfigFiles("sources")
})
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, 8)
}
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, 8)
}
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(":worldguard-libs:core")
val coreDeps = project(":worldguard-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")
}
}
}
}

View File

@ -1,68 +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.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
fun Project.applyPlatformAndCoreConfiguration(javaRelease: Int = 17) {
applyCommonConfiguration()
apply(plugin = "java")
apply(plugin = "maven-publish")
apply(plugin = "com.jfrog.artifactory")
applyCommonJavaConfiguration(
sourcesJar = true,
javaRelease = javaRelease,
banSlf4j = false
)
ext["internalVersion"] = "$version+${rootProject.ext["gitCommitHash"]}"
configure<PublishingExtension> {
publications {
register<MavenPublication>("maven") {
from(components["java"])
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(":worldguard-libs:core"))
//include(project(":worldguard-libs:${project.name.replace("worldguard-", "")}"))
include(project(":worldguard-core"))
relocate("org.flywaydb", "com.sk89q.worldguard.internal.flywaydb") {
include(dependency("org.flywaydb:flyway-core:3.0"))
}
exclude("com.google.code.findbugs:jsr305")
}
exclude("GradleStart**")
exclude(".cache")
exclude("LICENSE*")
exclude("META-INF/maven/**")
}
val javaComponent = components["java"] as AdhocComponentWithVariants
// I don't think we want this published (it's the shadow jar)
javaComponent.withVariantsFromConfiguration(configurations["shadowRuntimeElements"]) {
skip()
}
}

View File

@ -1,10 +0,0 @@
object Versions {
// const val PISTON = "0.4.3"
// const val AUTO_VALUE = "1.6.5"
const val WORLDEDIT = "7.3.0"
const val JUNIT = "5.9.1"
const val MOCKITO = "4.9.0"
const val SQUIRRELID = "0.3.2"
const val GUAVA = "31.1-jre"
const val FINDBUGS = "3.0.2"
}

View File

@ -7,7 +7,6 @@
<allow pkg="javax"/>
<allow pkg="org.junit"/>
<allow pkg="org.hamcrest"/>
<allow pkg="org.mockito"/>
<allow pkg="junit.framework"/>
<allow pkg="com.sk89q"/>
<allow pkg="com.google.common"/>

View File

@ -1,2 +1,4 @@
group=com.sk89q.worldguard
version=7.1.0-SNAPSHOT
org.gradle.parallel=true

View File

@ -0,0 +1,2 @@
#This file is generated by updateDaemonJvm
toolchainVersion=21

66
gradle/libs.versions.toml Normal file
View File

@ -0,0 +1,66 @@
[versions]
worldedit = "7.3.0"
# Minimum versions we apply to make dependencies support newer Java
minimumAsm = "9.7"
minimumJdependency = "2.10"
minimumTinyRemapper = "0.8.11"
# lang-version = ""
[libraries]
licenser = "gradle.plugin.org.cadixdev.gradle:licenser:0.6.1"
grgit = "org.ajoberstar.grgit:grgit-gradle:5.2.2"
shadow = "com.github.johnrengelman:shadow:8.1.1"
jfrog-buildinfo = "org.jfrog.buildinfo:build-info-extractor-gradle:5.2.0"
squirrelid = "org.enginehub:squirrelid:0.3.2"
autoService = "com.google.auto.service:auto-service:1.1.1"
jsr305 = "com.google.code.findbugs:jsr305:3.0.2"
jetbrains-annotations = "org.jetbrains:annotations:24.1.0"
junit-bom = "org.junit:junit-bom:5.10.2"
junit-jupiter-api.module = "org.junit.jupiter:junit-jupiter-api"
junit-jupiter-params.module = "org.junit.jupiter:junit-jupiter-params"
junit-jupiter-engine.module = "org.junit.jupiter:junit-jupiter-engine"
spigot = "org.spigotmc:spigot-api:1.21-R0.1-SNAPSHOT"
paperApi = "io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT"
paperLib = "io.papermc:paperlib:1.0.8"
dummypermscompat = "com.sk89q:dummypermscompat:1.10"
bstats-bukkit = "org.bstats:bstats-bukkit:2.2.1"
prtree = "org.khelekore:prtree:1.5.0"
flyway-core = "org.flywaydb:flyway-core:3.0"
commandbook = "com.sk89q:commandbook:2.3"
hamcrest-library = "org.hamcrest:hamcrest-library:2.2"
# Mojang-provided libraries, CHECK AGAINST MINECRAFT for versions
guava = "com.google.guava:guava:32.1.3-jre!!"
log4j-bom = "org.apache.logging.log4j:log4j-bom:2.22.1!!"
gson = "com.google.code.gson:gson:2.10.1!!"
fastutil = "it.unimi.dsi:fastutil:8.5.12!!"
# Bukkit-provided libraries, CHECK AGAINST SPIGOT for versions
# Note that we need to balance support for older MC versus working at all on newer ones, so the exact versions here
# may not be the same as the ones in the latest Bukkit API.
snakeyaml = "org.yaml:snakeyaml:2.0"
[libraries.worldedit-core]
module = "com.sk89q.worldedit:worldedit-core"
version.ref = "worldedit"
[libraries.worldedit-bukkit]
module = "com.sk89q.worldedit:worldedit-bukkit"
version.ref = "worldedit"
[libraries.worldedit-libs-ap]
module = "com.sk89q.worldedit.worldedit-libs:ap"
version.ref = "worldedit"

View File

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

View File

@ -1,7 +1,33 @@
pluginManagement {
repositories {
gradlePluginPortal()
}
}
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
}
logger.lifecycle("""
*******************************************
You are building WorldGuard!
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 = "worldguard"
includeBuild("build-logic")
include("worldguard-libs")
include("worldguard-libs:core")
include("worldguard-core")
//include("worldguard-libs:bukkit")
include("worldguard-bukkit")
listOf("bukkit", "core").forEach {
include("worldguard-$it")
}

View File

@ -2,38 +2,40 @@
plugins {
`java-library`
id("buildlogic.platform")
}
applyPlatformAndCoreConfiguration()
applyShadowConfiguration()
repositories {
maven {
name = "paper"
url = uri("https://repo.papermc.io/repository/maven-public/")
}
maven {
// TODO: Remove this once paper updated to adventure release
name = "adventure-snapshots"
url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")
}
}
configurations {
compileClasspath.get().extendsFrom(create("shadeOnly"))
val localImplementation = configurations.create("localImplementation") {
description = "Dependencies used locally, but provided by the runtime Bukkit implementation"
isCanBeConsumed = false
isCanBeResolved = false
}
configurations["compileOnly"].extendsFrom(localImplementation)
configurations["testImplementation"].extendsFrom(localImplementation)
dependencies {
"api"(project(":worldguard-core"))
"compileOnly"("io.papermc.paper:paper-api:1.20.6-R0.1-SNAPSHOT")
"runtimeOnly"("org.spigotmc:spigot-api:1.20.6-R0.1-SNAPSHOT") {
"api"(libs.worldedit.bukkit) { isTransitive = false }
"compileOnly"(libs.commandbook) { isTransitive = false }
// Technically this is api, but everyone should already have some form of the bukkit API
// Avoid pulling in another one, especially one so outdated.
"localImplementation"(libs.spigot) {
exclude("junit", "junit")
}
"api"("com.sk89q.worldedit:worldedit-bukkit:${Versions.WORLDEDIT}") { isTransitive = false }
"implementation"("com.google.guava:guava:${Versions.GUAVA}")
"compileOnly"("com.sk89q:commandbook:2.3") { isTransitive = false }
"shadeOnly"("io.papermc:paperlib:1.0.8")
"shadeOnly"("org.bstats:bstats-bukkit:3.0.1")
"compileOnly"(libs.jetbrains.annotations) {
because("Resolving Spigot annotations")
}
"testCompileOnly"(libs.jetbrains.annotations) {
because("Resolving Spigot annotations")
}
"compileOnly"(libs.paperApi) {
exclude("org.slf4j", "slf4j-api")
exclude("junit", "junit")
}
"implementation"(libs.paperLib)
"implementation"(libs.bstats.bukkit)
}
tasks.named<Copy>("processResources") {
@ -44,31 +46,23 @@
}
}
tasks.named<Jar>("jar") {
val projectVersion = project.version
inputs.property("projectVersion", projectVersion)
manifest {
attributes("Implementation-Version" to projectVersion)
}
}
tasks.named<ShadowJar>("shadowJar") {
configurations = listOf(project.configurations["shadeOnly"], project.configurations["runtimeClasspath"])
dependencies {
include(dependency(":worldguard-core"))
relocate("org.bstats", "com.sk89q.worldguard.bukkit.bstats") {
include(dependency("org.bstats:"))
}
relocate ("io.papermc.lib", "com.sk89q.worldguard.bukkit.paperlib") {
include(dependency("io.papermc:paperlib"))
}
relocate ("co.aikar.timings.lib", "com.sk89q.worldguard.bukkit.timingslib") {
include(dependency("co.aikar:minecraft-timings"))
}
relocate("org.bstats", "com.sk89q.worldguard.bukkit.bstats")
relocate("io.papermc.lib", "com.sk89q.worldguard.bukkit.paperlib")
}
}
tasks.named("assemble").configure {
dependsOn("shadowJar")
}
configure<PublishingExtension> {
publications.named<MavenPublication>("maven") {
from(components["java"])
}
}

View File

@ -55,23 +55,6 @@ public static int getPotionEffectBits(ItemStack item) {
return item.getDurability() & 0x3F;
}
/**
* Get a blacklist target for the given block.
*
* @param block the block
* @param effectiveMaterial The effective material, if different
* @return a target
*/
public static Target createTarget(Block block, Material effectiveMaterial) {
checkNotNull(block);
checkNotNull(block.getType());
if (block.getType() == effectiveMaterial) {
return createTarget(block.getType());
} else {
return createTarget(effectiveMaterial);
}
}
/**
* Get a blacklist target for the given block.
*

View File

@ -215,6 +215,7 @@ public void loadConfiguration() {
blockEnderDragonPortalCreation = getBoolean("mobs.block-enderdragon-portal-creation", false);
blockFireballExplosions = getBoolean("mobs.block-fireball-explosions", false);
blockFireballBlockDamage = getBoolean("mobs.block-fireball-block-damage", false);
blockWindChargeExplosions = getBoolean("mobs.block-windcharge-explosions", false);
antiWolfDumbness = getBoolean("mobs.anti-wolf-dumbness", false);
allowTamedSpawns = getBoolean("mobs.allow-tamed-spawns", true);
disableEndermanGriefing = getBoolean("mobs.disable-enderman-griefing", false);
@ -282,6 +283,7 @@ public void loadConfiguration() {
disableSculkGrowth = getBoolean("dynamics.disable-sculk-growth", false);
disableCropGrowth = getBoolean("dynamics.disable-crop-growth", false);
disableSoilDehydration = getBoolean("dynamics.disable-soil-dehydration", false);
disableSoilMoistureChange = getBoolean("dynamics.disable-soil-moisture-change", false);
disableCoralBlockFade = getBoolean("dynamics.disable-coral-block-fade", false);
disableCopperBlockFade = getBoolean("dynamics.disable-copper-block-fade", false);
allowedSnowFallOver = new HashSet<>(convertLegacyBlocks(getStringList("dynamics.snow-fall-blocks", null)));

View File

@ -96,7 +96,7 @@ public void onBreakBlock(final BreakBlockEvent event) {
event.filter(target -> {
if (!wcfg.getBlacklist().check(
new BlockBreakBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(target),
createTarget(target.getBlock(), event.getEffectiveMaterial())), false, false)) {
createTarget(target.getBlock())), false, false)) {
return false;
} else if (!wcfg.getBlacklist().check(
new ItemDestroyWithBlacklistEvent(localPlayer, BukkitAdapter.asBlockVector(target),
@ -124,7 +124,7 @@ public void onPlaceBlock(final PlaceBlockEvent event) {
final LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
event.filter(target -> wcfg.getBlacklist().check(new BlockPlaceBlacklistEvent(
localPlayer, BukkitAdapter.asBlockVector(target), createTarget(target.getBlock(), event.getEffectiveMaterial())), false, false));
localPlayer, BukkitAdapter.asBlockVector(target), createTarget(target.getBlock())), false, false));
}
@EventHandler(ignoreCancelled = true)
@ -143,7 +143,7 @@ public void onUseBlock(final UseBlockEvent event) {
final LocalPlayer localPlayer = getPlugin().wrapPlayer(player);
event.filter(target -> wcfg.getBlacklist().check(new BlockInteractBlacklistEvent(
localPlayer, BukkitAdapter.asBlockVector(target), createTarget(target.getBlock(), event.getEffectiveMaterial())), false, false));
localPlayer, BukkitAdapter.asBlockVector(target), createTarget(target.getBlock())), false, false));
}
@EventHandler(ignoreCancelled = true)

View File

@ -101,12 +101,14 @@ public void onUseBlock(final UseBlockEvent event) {
if (rootCause instanceof Player) {
final Player player = (Player) rootCause;
final Material material = event.getEffectiveMaterial();
if (!hasBuildPermission(player, "block." + material.name().toLowerCase() + ".interact")
&& !hasBuildPermission(player, "block.interact." + material.name().toLowerCase())) {
boolean blocked = event.filter(loc -> {
String blacklistName = loc.getBlock().getType().name().toLowerCase();
return hasBuildPermission(player, "block." + blacklistName + ".interact") ||
hasBuildPermission(player, "block.interact." + blacklistName);
}, true);
if (blocked && !event.isSilent()) {
tellErrorMessage(player, event.getWorld());
event.setCancelled(true);
}
}
}

View File

@ -50,6 +50,7 @@
import io.papermc.paper.event.player.PlayerOpenSignEvent;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.ExplosionResult;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
@ -66,6 +67,8 @@
import org.bukkit.block.data.Waterlogged;
import org.bukkit.block.data.type.Dispenser;
import org.bukkit.entity.AreaEffectCloud;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.BreezeWindCharge;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
@ -79,6 +82,7 @@
import org.bukkit.entity.Player;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.ThrownPotion;
import org.bukkit.entity.WindCharge;
import org.bukkit.entity.minecart.HopperMinecart;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
@ -112,8 +116,10 @@
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntityInteractEvent;
import org.bukkit.event.entity.EntityKnockbackByEntityEvent;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.entity.EntityTameEvent;
import org.bukkit.event.entity.EntityUnleashEvent;
@ -176,9 +182,11 @@ public EventAbstractionListener(WorldGuardPlugin plugin) {
public void registerEvents() {
super.registerEvents();
if (PaperLib.isPaper()) {
PluginManager pm = getPlugin().getServer().getPluginManager();
if (PaperLib.isPaper()) {
pm.registerEvents(new EventAbstractionListener.PaperListener(), getPlugin());
} else {
pm.registerEvents(new EventAbstractionListener.SpigotListener(), getPlugin());
}
}
@ -218,8 +226,8 @@ public void onBlockPlace(BlockPlaceEvent event) {
Events.fireToCancel(event, new BreakBlockEvent(event, create(event.getPlayer()), previousState.getLocation(), previousState.getType()));
}
if (!event.isCancelled()) {
ItemStack itemStack = new ItemStack(event.getBlockPlaced().getType(), 1);
ItemStack itemStack = event.getItemInHand();
if (!event.isCancelled() && itemStack.getType() != Material.AIR) {
Events.fireToCancel(event, new UseItemEvent(event, create(event.getPlayer()), event.getPlayer().getWorld(), itemStack));
}
@ -323,10 +331,10 @@ public void onEntityChangeBlock(EntityChangeBlockEvent event) {
// Fire two events: one as BREAK and one as PLACE
if (toType != Material.AIR && fromType != Material.AIR) {
BreakBlockEvent breakDelagate = new BreakBlockEvent(event, cause, block);
setDelegateEventMaterialOptions(breakDelagate, fromType, toType);
BreakBlockEvent breakDelegate = new BreakBlockEvent(event, cause, block);
setDelegateEventMaterialOptions(breakDelegate, fromType, toType);
boolean denied;
if (!(denied = Events.fireToCancel(event, breakDelagate))) {
if (!(denied = Events.fireToCancel(event, breakDelegate))) {
PlaceBlockEvent placeDelegate = new PlaceBlockEvent(event, cause, block.getLocation(), toType);
setDelegateEventMaterialOptions(placeDelegate, fromType, toType);
denied = Events.fireToCancel(event, placeDelegate);
@ -354,10 +362,29 @@ public void onEntityChangeBlock(EntityChangeBlockEvent event) {
}
private static <T extends EntityEvent & Cancellable> void handleKnockback(T event, Entity damager) {
final DamageEntityEvent eventToFire = new DamageEntityEvent(event, create(damager), event.getEntity());
if (damager instanceof BreezeWindCharge) {
eventToFire.getRelevantFlags().add(Flags.BREEZE_WIND_CHARGE);
} else if (damager instanceof WindCharge) {
eventToFire.getRelevantFlags().add(Flags.WIND_CHARGE_BURST);
}
Events.fireToCancel(event, eventToFire);
}
@SuppressWarnings("UnstableApiUsage")
@EventHandler(ignoreCancelled = true)
public void onEntityExplode(EntityExplodeEvent event) {
Entity entity = event.getEntity();
if (event.getExplosionResult() == ExplosionResult.TRIGGER_BLOCK) {
UseBlockEvent useEvent = new UseBlockEvent(event, create(entity), event.getLocation().getWorld(), event.blockList(), Material.AIR);
useEvent.getRelevantFlags().add(Entities.getExplosionFlag(entity));
useEvent.setSilent(true);
Events.fireBulkEventToCancel(event, useEvent);
} else if (event.getExplosionResult() == ExplosionResult.DESTROY || event.getExplosionResult() == ExplosionResult.DESTROY_WITH_DECAY) {
Events.fireBulkEventToCancel(event, new BreakBlockEvent(event, create(entity), event.getLocation().getWorld(), event.blockList(), Material.AIR));
}
if (entity instanceof Creeper) {
Cause.untrackParentCause(entity);
}
@ -887,11 +914,19 @@ public void onEntityDamage(EntityDamageEvent event) {
@EventHandler(ignoreCancelled = true)
public void onEntityCombust(EntityCombustEvent event) {
if (event instanceof EntityCombustByBlockEvent) {
if (event instanceof EntityCombustByBlockEvent combustByBlockEvent) {
// at the time of writing, spigot is throwing null for the event's combuster. this causes lots of issues downstream.
// whenever (i mean if ever) it is fixed, use getCombuster again instead of the current block
Events.fireToCancel(event, new DamageEntityEvent(event, create(event.getEntity().getLocation().getBlock()), event.getEntity()));
Block combuster = combustByBlockEvent.getCombuster();
Events.fireToCancel(event, new DamageEntityEvent(event,
create(combuster == null ? event.getEntity().getLocation().getBlock() : combuster), event.getEntity()));
} else if (event instanceof EntityCombustByEntityEvent) {
if (event.getEntity() instanceof Arrow) {
// this only happens from the Flame enchant. igniting arrows in other ways (eg with lava) doesn't even
// throw the combust event, not even the CombustByBlock event... they're also very buggy and don't even
// show as lit on the client consistently
return;
}
Events.fireToCancel(event, new DamageEntityEvent(event, create(((EntityCombustByEntityEvent) event).getCombuster()), event.getEntity()));
}
}
@ -1007,7 +1042,6 @@ public void onPotionSplash(PotionSplashEvent event) {
// Fire item interaction event
Events.fireToCancel(event, new UseItemEvent(event, cause, world, potion.getItem()));
// Fire entity interaction event
if (!event.isCancelled()) {
int blocked = 0;
@ -1019,8 +1053,11 @@ public void onPotionSplash(PotionSplashEvent event) {
? new DamageEntityEvent(event, cause, affected) :
new UseEntityEvent(event, cause, affected);
// Consider the potion splash flag
// Consider extra relevant flags
delegate.getRelevantFlags().add(Flags.POTION_SPLASH);
if (potion.getShooter() instanceof LivingEntity shooter && !(shooter instanceof Player) && affected instanceof Player) {
delegate.getRelevantFlags().add(Flags.MOB_DAMAGE);
}
if (Events.fireAndTestCancel(delegate)) {
event.setIntensity(affected, 0);
@ -1213,9 +1250,9 @@ private static <T extends Event & Cancellable> void handleInventoryHolderUse(T o
useBlockEvent.setAllowed(true);
}
Events.fireToCancel(originalEvent, useBlockEvent);
} else if (holder instanceof DoubleChest) {
InventoryHolder left = ((DoubleChest) holder).getLeftSide();
InventoryHolder right = ((DoubleChest) holder).getRightSide();
} else if (holder instanceof DoubleChest doubleChest) {
InventoryHolder left = PaperLib.isPaper() ? doubleChest.getLeftSide(false) : doubleChest.getLeftSide();
InventoryHolder right = PaperLib.isPaper() ? doubleChest.getRightSide(false) : doubleChest.getRightSide();
if (left instanceof Chest) {
Events.fireToCancel(originalEvent, new UseBlockEvent(originalEvent, cause, ((Chest) left).getBlock()));
}
@ -1261,7 +1298,7 @@ private static void playDenyEffect(Location location) {
}
}
private class PaperListener implements Listener {
private static class PaperListener implements Listener {
@EventHandler(ignoreCancelled = true)
public void onEntityTransform(EntityZapEvent event) {
Events.fireToCancel(event, new DamageEntityEvent(event, create(event.getBolt()), event.getEntity()));
@ -1274,5 +1311,18 @@ public void onSignOpen(PlayerOpenSignEvent event) {
Events.fireToCancel(event, new UseBlockEvent(event, create(event.getPlayer()), event.getSign().getBlock()));
}
}
@EventHandler(ignoreCancelled = true)
public void onEntityKnockbackByEntity(com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent event) {
handleKnockback(event, event.getHitBy());
}
}
@SuppressWarnings("removal")
private static class SpigotListener implements Listener {
@EventHandler(ignoreCancelled = true)
public void onEntityKnockbackByEntity(EntityKnockbackByEntityEvent event) {
handleKnockback(event, event.getSourceEntity());
}
}
}

View File

@ -61,6 +61,7 @@
import org.bukkit.event.Event;
import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.player.PlayerTakeLecternBookEvent;
import org.bukkit.event.vehicle.VehicleExitEvent;
@ -173,7 +174,7 @@ public void onPlaceBlock(final PlaceBlockEvent event) {
/* Flint and steel, fire charge, etc. */
if (Materials.isFire(type)) {
Block block = event.getCause().getFirstBlock();
boolean fire = block != null && Materials.isFire(type);
boolean fire = block != null && Materials.isFire(block.getType());
boolean lava = block != null && Materials.isLava(block.getType());
List<StateFlag> flags = new ArrayList<>();
flags.add(Flags.BLOCK_PLACE);
@ -244,13 +245,13 @@ public void onUseBlock(final UseBlockEvent event) {
if (!isRegionSupportEnabled(event.getWorld())) return; // Region support disabled
if (isWhitelisted(event.getCause(), event.getWorld(), false)) return; // Whitelisted cause
final Material type = event.getEffectiveMaterial();
final RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
final RegionAssociable associable = createRegionAssociable(event.getCause());
event.filter((Predicate<Location>) target -> {
boolean canUse;
String what;
final Material type = target.getBlock().getType();
/* Saplings, etc. */
if (Materials.isConsideredBuildingIfUsed(type)) {
@ -410,13 +411,15 @@ public void onUseEntity(UseEntityEvent event) {
canUse = event.getRelevantFlags().isEmpty() || query.queryState(BukkitAdapter.adapt(target), associable, combine(event)) != State.DENY;
what = "use that";
/* Paintings, item frames, etc. */
} else if (Entities.isConsideredBuildingIfUsed(entity)) {
} else if (Entities.isConsideredBuildingIfUsed(entity)
// weird case since sneak+interact is chest access and not ride
|| type == EntityType.CHEST_BOAT && event.getOriginalEvent() instanceof InventoryOpenEvent) {
if ((type == EntityType.ITEM_FRAME || type == EntityType.GLOW_ITEM_FRAME)
&& event.getCause().getFirstPlayer() != null
&& ((ItemFrame) entity).getItem().getType() != Material.AIR) {
canUse = query.testBuild(BukkitAdapter.adapt(target), associable, combine(event, Flags.ITEM_FRAME_ROTATE));
what = "change that";
} else if (Entities.isMinecart(type)) {
} else if (Entities.isMinecart(type) || type == EntityType.CHEST_BOAT) {
canUse = query.testBuild(BukkitAdapter.adapt(target), associable, combine(event, Flags.CHEST_ACCESS));
what = "open that";
} else {

View File

@ -56,6 +56,7 @@
import org.bukkit.event.block.BlockSpreadEvent;
import org.bukkit.event.block.EntityBlockFormEvent;
import org.bukkit.event.block.LeavesDecayEvent;
import org.bukkit.event.block.MoistureChangeEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
@ -726,4 +727,24 @@ public void onBlockExplode(BlockExplodeEvent event) {
}
}
/**
* Called when the moisture level of a block changes
*/
@EventHandler(ignoreCancelled = true)
public void onMoistureChange(MoistureChangeEvent event) {
WorldConfiguration wcfg = getWorldConfig(event.getBlock().getWorld());
if (wcfg.disableSoilMoistureChange) {
event.setCancelled(true);
return;
}
if (wcfg.useRegions) {
if (!StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.queryState(BukkitAdapter.adapt(event.getBlock().getLocation()), (RegionAssociable) null, Flags.MOISTURE_CHANGE))) {
event.setCancelled(true);
}
}
}
}

View File

@ -44,6 +44,7 @@
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.AbstractWindCharge;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.EnderCrystal;
@ -60,6 +61,7 @@
import org.bukkit.entity.Projectile;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.WindCharge;
import org.bukkit.entity.Wither;
import org.bukkit.entity.WitherSkull;
import org.bukkit.entity.Wolf;
@ -311,13 +313,17 @@ private void onEntityDamageByProjectile(EntityDamageByEntityEvent event) {
return;
}
}
if (event.getDamager() instanceof Fireball) {
Fireball fireball = (Fireball) event.getDamager();
if (event.getDamager() instanceof Fireball fireball) {
if (fireball instanceof WitherSkull) {
if (wcfg.blockWitherSkullExplosions) {
event.setCancelled(true);
return;
}
} else if (fireball instanceof AbstractWindCharge) {
if (wcfg.blockWindChargeExplosions) {
event.setCancelled(true);
return;
}
} else {
if (wcfg.blockFireballExplosions) {
event.setCancelled(true);
@ -326,7 +332,7 @@ private void onEntityDamageByProjectile(EntityDamageByEntityEvent event) {
}
if (wcfg.useRegions) {
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
if (!query.testState(localPlayer.getLocation(), localPlayer, Flags.GHAST_FIREBALL) && wcfg.explosionFlagCancellation) {
if (!query.testState(localPlayer.getLocation(), localPlayer, Entities.getExplosionFlag(event.getDamager())) && wcfg.explosionFlagCancellation) {
event.setCancelled(true);
return;
}
@ -483,6 +489,11 @@ public void onEntityExplode(EntityExplodeEvent event) {
event.blockList().clear();
return;
}
} else if (ent instanceof AbstractWindCharge) {
if (wcfg.blockWindChargeExplosions) {
event.setCancelled(true);
return;
}
} else {
if (wcfg.blockFireballExplosions) {
event.setCancelled(true);
@ -493,10 +504,10 @@ public void onEntityExplode(EntityExplodeEvent event) {
return;
}
}
// allow wither skull blocking since there is no dedicated flag atm
if (wcfg.useRegions) {
if (wcfg.useRegions && !(ent instanceof WindCharge)) {
for (Block block : event.blockList()) {
if (!WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().getApplicableRegions(BukkitAdapter.adapt(block.getLocation())).testState(null, Flags.GHAST_FIREBALL)) {
if (!WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.testState(BukkitAdapter.adapt(block.getLocation()), null, Entities.getExplosionFlag(ent))) {
event.blockList().clear();
if (wcfg.explosionFlagCancellation) event.setCancelled(true);
return;
@ -514,8 +525,8 @@ public void onEntityExplode(EntityExplodeEvent event) {
}
if (wcfg.useRegions) {
for (Block block : event.blockList()) {
if (!StateFlag.test(WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().queryState(BukkitAdapter.adapt(block.getLocation()),
(RegionAssociable) null, Flags.WITHER_DAMAGE))) {
if (!WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.testState(BukkitAdapter.adapt(block.getLocation()), null, Flags.WITHER_DAMAGE)) {
event.blockList().clear();
event.setCancelled(true);
return;
@ -530,7 +541,8 @@ public void onEntityExplode(EntityExplodeEvent event) {
}
if (wcfg.useRegions) {
for (Block block : event.blockList()) {
if (!WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery().getApplicableRegions(BukkitAdapter.adapt(block.getLocation())).testState(null, Flags.OTHER_EXPLOSION)) {
if (!WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery()
.testState(BukkitAdapter.adapt(block.getLocation()), null, Flags.OTHER_EXPLOSION)) {
event.blockList().clear();
if (wcfg.explosionFlagCancellation) event.setCancelled(true);
return;
@ -539,7 +551,6 @@ public void onEntityExplode(EntityExplodeEvent event) {
}
}
if (wcfg.signChestProtection) {
for (Block block : event.blockList()) {
if (wcfg.isChestProtected(BukkitAdapter.adapt(block.getLocation()))) {
@ -592,6 +603,11 @@ public void onExplosionPrime(ExplosionPrimeEvent event) {
event.setCancelled(true);
return;
}
} else if (event instanceof AbstractWindCharge) {
if (wcfg.blockWindChargeExplosions) {
event.setCancelled(true);
return;
}
}
}

View File

@ -350,6 +350,11 @@ public void onItemHeldChange(PlayerItemHeldEvent event) {
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerTeleport(PlayerTeleportEvent event) {
if (event.getTo() == null) {
// The target location for PlayerTeleportEvents can be null.
// Those events will be ignored by the server, so we can ignore them too.
return;
}
Player player = event.getPlayer();
if (com.sk89q.worldguard.bukkit.util.Entities.isNPC(player)) return;
LocalPlayer localPlayer = getPlugin().wrapPlayer(player);

View File

@ -19,15 +19,21 @@
package com.sk89q.worldguard.bukkit.util;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.StateFlag;
import org.bukkit.entity.Allay;
import org.bukkit.entity.Ambient;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.BreezeWindCharge;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.EnderCrystal;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Fireball;
import org.bukkit.entity.Firework;
import org.bukkit.entity.Flying;
import org.bukkit.entity.Hanging;
import org.bukkit.entity.LivingEntity;
@ -43,11 +49,14 @@
import org.bukkit.entity.TNTPrimed;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.Vehicle;
import org.bukkit.entity.WindCharge;
import org.bukkit.entity.Wither;
import org.bukkit.entity.minecart.ExplosiveMinecart;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.projectiles.ProjectileSource;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public final class Entities {
@ -237,7 +246,7 @@ public static boolean isAoECloud(EntityType type) {
* This is true for custom creations or the summon command.
*
* @param spawnReason the reason
* @return true if considerd plugin spawning
* @return true if considered plugin spawning
*/
public static boolean isPluginSpawning(CreatureSpawnEvent.SpawnReason spawnReason) {
return switch (spawnReason) {
@ -245,4 +254,24 @@ public static boolean isPluginSpawning(CreatureSpawnEvent.SpawnReason spawnReaso
default -> false;
};
}
/**
* Get the explosion flag relevant for an entity type.
* @param entity the entity
* @return the relevant StateFlag or OTHER_EXPLOSION if none is matching
*/
public static @Nonnull StateFlag getExplosionFlag(Entity entity) {
return switch (entity) {
case BreezeWindCharge breezeWindCharge -> Flags.BREEZE_WIND_CHARGE;
case WindCharge windCharge -> Flags.WIND_CHARGE_BURST;
case Firework firework -> Flags.FIREWORK_DAMAGE;
case Fireball fireball -> Flags.GHAST_FIREBALL;
case Wither wither -> Flags.WITHER_DAMAGE;
case Creeper creeper -> Flags.CREEPER_EXPLOSION;
case TNTPrimed tnt -> Flags.TNT;
case ExplosiveMinecart minecart -> Flags.TNT;
case EnderDragon dragon -> Flags.ENDERDRAGON_BLOCK_DAMAGE;
case null, default -> Flags.OTHER_EXPLOSION;
};
}
}

View File

@ -80,6 +80,10 @@ private static void putMaterialTag(Tag<Material> tag, Integer value) {
ENTITY_ITEMS.put(EntityType.ARMOR_STAND, Material.ARMOR_STAND);
ENTITY_ITEMS.put(EntityType.END_CRYSTAL, Material.END_CRYSTAL);
// preset some tags to a default value, override some of them:
putMaterialTag(Tag.DOORS, MODIFIED_ON_RIGHT);
putMaterialTag(Tag.TRAPDOORS, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.AIR, 0);
MATERIAL_FLAGS.put(Material.STONE, 0);
MATERIAL_FLAGS.put(Material.GRASS_BLOCK, 0);
@ -150,12 +154,6 @@ private static void putMaterialTag(Tag<Material> tag, Integer value) {
MATERIAL_FLAGS.put(Material.CAKE, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.REPEATER, MODIFIED_ON_RIGHT);
// MATERIAL_FLAGS.put(Material.STAINED_GLASS, 0);
MATERIAL_FLAGS.put(Material.ACACIA_TRAPDOOR, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.BIRCH_TRAPDOOR, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.DARK_OAK_TRAPDOOR, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.JUNGLE_TRAPDOOR, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.OAK_TRAPDOOR, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.SPRUCE_TRAPDOOR, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.INFESTED_STONE, 0);
MATERIAL_FLAGS.put(Material.INFESTED_STONE_BRICKS, 0);
MATERIAL_FLAGS.put(Material.INFESTED_MOSSY_STONE_BRICKS, 0);
@ -227,11 +225,6 @@ private static void putMaterialTag(Tag<Material> tag, Integer value) {
MATERIAL_FLAGS.put(Material.IRON_TRAPDOOR, 0);
MATERIAL_FLAGS.put(Material.RED_SANDSTONE, 0);
MATERIAL_FLAGS.put(Material.RED_SANDSTONE_STAIRS, 0);
MATERIAL_FLAGS.put(Material.SPRUCE_DOOR, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.BIRCH_DOOR, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.JUNGLE_DOOR, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.ACACIA_DOOR, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.DARK_OAK_DOOR, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.DIRT_PATH, 0);
MATERIAL_FLAGS.put(Material.CHORUS_PLANT, 0);
@ -677,7 +670,6 @@ private static void putMaterialTag(Tag<Material> tag, Integer value) {
MATERIAL_FLAGS.put(Material.CRIMSON_FUNGUS, 0);
MATERIAL_FLAGS.put(Material.CRIMSON_NYLIUM, 0);
MATERIAL_FLAGS.put(Material.CRIMSON_ROOTS, 0);
MATERIAL_FLAGS.put(Material.CRIMSON_TRAPDOOR, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.CRYING_OBSIDIAN, 0);
MATERIAL_FLAGS.put(Material.GILDED_BLACKSTONE, 0);
MATERIAL_FLAGS.put(Material.LODESTONE, 0);
@ -718,7 +710,6 @@ private static void putMaterialTag(Tag<Material> tag, Integer value) {
MATERIAL_FLAGS.put(Material.WARPED_FUNGUS_ON_A_STICK, 0);
MATERIAL_FLAGS.put(Material.WARPED_NYLIUM, 0);
MATERIAL_FLAGS.put(Material.WARPED_ROOTS, 0);
MATERIAL_FLAGS.put(Material.WARPED_TRAPDOOR, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.WARPED_WART_BLOCK, 0);
MATERIAL_FLAGS.put(Material.WEEPING_VINES, 0);
MATERIAL_FLAGS.put(Material.WEEPING_VINES_PLANT, 0);
@ -843,9 +834,47 @@ private static void putMaterialTag(Tag<Material> tag, Integer value) {
MATERIAL_FLAGS.put(Material.ARMADILLO_SCUTE, 0);
MATERIAL_FLAGS.put(Material.WOLF_ARMOR, 0);
// Generated via tag
putMaterialTag(Tag.WOODEN_DOORS, MODIFIED_ON_RIGHT);
putMaterialTag(Tag.WOODEN_TRAPDOORS, MODIFIED_ON_RIGHT);
// 1.21
MATERIAL_FLAGS.put(Material.CHISELED_TUFF, 0);
MATERIAL_FLAGS.put(Material.POLISHED_TUFF, 0);
MATERIAL_FLAGS.put(Material.TUFF_BRICKS, 0);
MATERIAL_FLAGS.put(Material.CHISELED_TUFF_BRICKS, 0);
MATERIAL_FLAGS.put(Material.HEAVY_CORE, 0);
MATERIAL_FLAGS.put(Material.CHISELED_COPPER, 0);
MATERIAL_FLAGS.put(Material.EXPOSED_CHISELED_COPPER, 0);
MATERIAL_FLAGS.put(Material.WEATHERED_CHISELED_COPPER, 0);
MATERIAL_FLAGS.put(Material.OXIDIZED_CHISELED_COPPER, 0);
MATERIAL_FLAGS.put(Material.WAXED_CHISELED_COPPER, 0);
MATERIAL_FLAGS.put(Material.WAXED_EXPOSED_CHISELED_COPPER, 0);
MATERIAL_FLAGS.put(Material.WAXED_WEATHERED_CHISELED_COPPER, 0);
MATERIAL_FLAGS.put(Material.WAXED_OXIDIZED_CHISELED_COPPER, 0);
MATERIAL_FLAGS.put(Material.CRAFTER, 0);
MATERIAL_FLAGS.put(Material.FLOW_BANNER_PATTERN, 0);
MATERIAL_FLAGS.put(Material.GUSTER_BANNER_PATTERN, 0);
MATERIAL_FLAGS.put(Material.COPPER_GRATE, 0);
MATERIAL_FLAGS.put(Material.WEATHERED_COPPER_GRATE, 0);
MATERIAL_FLAGS.put(Material.EXPOSED_COPPER_GRATE, 0);
MATERIAL_FLAGS.put(Material.OXIDIZED_COPPER_GRATE, 0);
MATERIAL_FLAGS.put(Material.WAXED_COPPER_GRATE, 0);
MATERIAL_FLAGS.put(Material.WAXED_WEATHERED_COPPER_GRATE, 0);
MATERIAL_FLAGS.put(Material.WAXED_EXPOSED_COPPER_GRATE, 0);
MATERIAL_FLAGS.put(Material.WAXED_OXIDIZED_COPPER_GRATE, 0);
MATERIAL_FLAGS.put(Material.COPPER_BULB, 0);
MATERIAL_FLAGS.put(Material.WEATHERED_COPPER_BULB, 0);
MATERIAL_FLAGS.put(Material.EXPOSED_COPPER_BULB, 0);
MATERIAL_FLAGS.put(Material.OXIDIZED_COPPER_BULB, 0);
MATERIAL_FLAGS.put(Material.WAXED_COPPER_BULB, 0);
MATERIAL_FLAGS.put(Material.WAXED_WEATHERED_COPPER_BULB, 0);
MATERIAL_FLAGS.put(Material.WAXED_EXPOSED_COPPER_BULB, 0);
MATERIAL_FLAGS.put(Material.WAXED_OXIDIZED_COPPER_BULB, 0);
MATERIAL_FLAGS.put(Material.TRIAL_SPAWNER, 0);
MATERIAL_FLAGS.put(Material.TRIAL_KEY, 0);
MATERIAL_FLAGS.put(Material.OMINOUS_TRIAL_KEY, 0);
MATERIAL_FLAGS.put(Material.VAULT, MODIFIED_ON_RIGHT);
MATERIAL_FLAGS.put(Material.OMINOUS_BOTTLE, 0);
MATERIAL_FLAGS.put(Material.BREEZE_ROD, 0);
MATERIAL_FLAGS.put(Material.WIND_CHARGE, 0);
putMaterialTag(Tag.SHULKER_BOXES, MODIFIED_ON_RIGHT);
putMaterialTag(Tag.ITEMS_BOATS, 0);
putMaterialTag(Tag.BANNERS, 0);
@ -864,7 +893,6 @@ private static void putMaterialTag(Tag<Material> tag, Integer value) {
putMaterialTag(Tag.ALL_SIGNS, 0);
putMaterialTag(Tag.SMALL_FLOWERS, 0);
putMaterialTag(Tag.BEDS, MODIFIED_ON_RIGHT);
putMaterialTag(Tag.ITEMS_MUSIC_DISCS, 0);
putMaterialTag(Tag.ITEMS_BANNERS, 0);
putMaterialTag(Tag.FENCE_GATES, MODIFIED_ON_RIGHT);
putMaterialTag(Tag.FENCES, 0);
@ -903,6 +931,9 @@ private static void putMaterialTag(Tag<Material> tag, Integer value) {
if (isSpawnEgg(material)) {
MATERIAL_FLAGS.put(material, 0);
}
if (material.name().startsWith("MUSIC_DISC_")) {
MATERIAL_FLAGS.put(material, 0);
}
if (!MATERIAL_FLAGS.containsKey(material)) {
logger.fine("Missing material definition for " + (material.isBlock() ? "block " : "item ") + material.name());
}
@ -910,15 +941,15 @@ private static void putMaterialTag(Tag<Material> tag, Integer value) {
// DAMAGE_EFFECTS.add(PotionEffectType.SPEED);
DAMAGE_EFFECTS.add(PotionEffectType.SLOWNESS);
// DAMAGE_EFFECTS.add(PotionEffectType.FAST_DIGGING);
// DAMAGE_EFFECTS.add(PotionEffectType.HASTE);
DAMAGE_EFFECTS.add(PotionEffectType.MINING_FATIGUE);
// DAMAGE_EFFECTS.add(PotionEffectType.INCREASE_DAMAGE);
// DAMAGE_EFFECTS.add(PotionEffectType.HEAL);
// DAMAGE_EFFECTS.add(PotionEffectType.STRENGTH);
// DAMAGE_EFFECTS.add(PotionEffectType.INSTANT_HEALTH);
DAMAGE_EFFECTS.add(PotionEffectType.INSTANT_DAMAGE);
// DAMAGE_EFFECTS.add(PotionEffectType.JUMP);
// DAMAGE_EFFECTS.add(PotionEffectType.JUMP_BOOST);
DAMAGE_EFFECTS.add(PotionEffectType.NAUSEA);
// DAMAGE_EFFECTS.add(PotionEffectType.REGENERATION);
// DAMAGE_EFFECTS.add(PotionEffectType.DAMAGE_RESISTANCE);
// DAMAGE_EFFECTS.add(PotionEffectType.RESISTANCE);
// DAMAGE_EFFECTS.add(PotionEffectType.FIRE_RESISTANCE);
// DAMAGE_EFFECTS.add(PotionEffectType.WATER_BREATHING);
// DAMAGE_EFFECTS.add(PotionEffectType.INVISIBILITY);
@ -941,6 +972,11 @@ private static void putMaterialTag(Tag<Material> tag, Integer value) {
DAMAGE_EFFECTS.add(PotionEffectType.BAD_OMEN);
// DAMAGE_EFFECTS.add(PotionEffectType.HERO_OF_THE_VILLAGE);
DAMAGE_EFFECTS.add(PotionEffectType.DARKNESS);
DAMAGE_EFFECTS.add(PotionEffectType.TRIAL_OMEN);
DAMAGE_EFFECTS.add(PotionEffectType.WIND_CHARGED);
DAMAGE_EFFECTS.add(PotionEffectType.WEAVING);
DAMAGE_EFFECTS.add(PotionEffectType.OOZING);
DAMAGE_EFFECTS.add(PotionEffectType.INFESTED);
}
private Materials() {
@ -1127,6 +1163,7 @@ public static boolean isInventoryBlock(Material material) {
|| material == Material.BLAST_FURNACE
|| material == Material.SMOKER
|| material == Material.CHISELED_BOOKSHELF
|| material == Material.CRAFTER
|| Tag.ITEMS_CHEST_BOATS.isTagged(material)
|| Tag.SHULKER_BOXES.isTagged(material);
}
@ -1140,10 +1177,11 @@ public static EntityType getEntitySpawnEgg(Material material) {
case ALLAY_SPAWN_EGG -> EntityType.ALLAY;
case ARMADILLO_SPAWN_EGG -> EntityType.ARMADILLO;
case AXOLOTL_SPAWN_EGG -> EntityType.AXOLOTL;
case SPIDER_SPAWN_EGG -> EntityType.SPIDER;
case BAT_SPAWN_EGG -> EntityType.BAT;
case BEE_SPAWN_EGG -> EntityType.BEE;
case BLAZE_SPAWN_EGG -> EntityType.BLAZE;
case BOGGED_SPAWN_EGG -> EntityType.BOGGED;
case BREEZE_SPAWN_EGG -> EntityType.BREEZE;
case CAT_SPAWN_EGG -> EntityType.CAT;
case CAMEL_SPAWN_EGG -> EntityType.CAMEL;
case CAVE_SPIDER_SPAWN_EGG -> EntityType.CAVE_SPIDER;
@ -1193,6 +1231,7 @@ public static EntityType getEntitySpawnEgg(Material material) {
case SLIME_SPAWN_EGG -> EntityType.SLIME;
case SNIFFER_SPAWN_EGG -> EntityType.SNIFFER;
case SNOW_GOLEM_SPAWN_EGG -> EntityType.SNOW_GOLEM;
case SPIDER_SPAWN_EGG -> EntityType.SPIDER;
case SQUID_SPAWN_EGG -> EntityType.SQUID;
case STRAY_SPAWN_EGG -> EntityType.STRAY;
case STRIDER_SPAWN_EGG -> EntityType.STRIDER;
@ -1276,15 +1315,15 @@ public static boolean isVine(Material newType) {
*/
public static boolean isUseFlagApplicable(Material material) {
if (Tag.BUTTONS.isTagged(material)
|| Tag.WOODEN_DOORS.isTagged(material)
|| Tag.WOODEN_TRAPDOORS.isTagged(material)
|| Tag.DOORS.isTagged(material)
|| Tag.TRAPDOORS.isTagged(material)
|| Tag.FENCE_GATES.isTagged(material)
|| Tag.PRESSURE_PLATES.isTagged(material)) {
return true;
}
return switch (material) {
case LEVER, LECTERN, ENCHANTING_TABLE, BELL, LOOM,
CARTOGRAPHY_TABLE, STONECUTTER, GRINDSTONE -> true;
CARTOGRAPHY_TABLE, STONECUTTER, GRINDSTONE, VAULT -> true;
default -> false;
};
}
@ -1367,15 +1406,13 @@ public static boolean hasDamageEffect(Collection<PotionEffect> effects) {
* @return true if equippable armor
*/
public static boolean isArmor(Material type) {
if (Tag.ITEMS_HEAD_ARMOR.isTagged(type) || Tag.ITEMS_CHEST_ARMOR.isTagged(type) ||
Tag.ITEMS_LEG_ARMOR.isTagged(type) || Tag.ITEMS_FOOT_ARMOR.isTagged(type) ||
Tag.ITEMS_SKULLS.isTagged(type)) {
return true;
}
return switch (type) {
case LEATHER_HELMET, LEATHER_CHESTPLATE, LEATHER_LEGGINGS, LEATHER_BOOTS,
CHAINMAIL_HELMET, CHAINMAIL_CHESTPLATE, CHAINMAIL_LEGGINGS, CHAINMAIL_BOOTS,
IRON_HELMET, IRON_CHESTPLATE, IRON_LEGGINGS, IRON_BOOTS,
DIAMOND_HELMET, DIAMOND_CHESTPLATE, DIAMOND_LEGGINGS, DIAMOND_BOOTS,
GOLDEN_HELMET, GOLDEN_CHESTPLATE, GOLDEN_LEGGINGS, GOLDEN_BOOTS,
NETHERITE_HELMET, NETHERITE_CHESTPLATE, NETHERITE_LEGGINGS, NETHERITE_BOOTS,
TURTLE_HELMET, ELYTRA ->
true;
case CARVED_PUMPKIN, ELYTRA -> true;
default -> false;
};
}
@ -1458,6 +1495,9 @@ public static boolean isToolApplicable(Material toolMaterial, Material targetMat
case SUSPICIOUS_GRAVEL, SUSPICIOUS_SAND -> true;
default -> false;
};
case WRITTEN_BOOK:
case WRITABLE_BOOK:
return targetMaterial == Material.LECTERN;
default:
return false;
}
@ -1468,25 +1508,16 @@ public static boolean isFire(Material type) {
}
public static boolean isWaxedCopper(Material type) {
return switch (type) {
case WAXED_COPPER_BLOCK, WAXED_EXPOSED_COPPER, WAXED_WEATHERED_COPPER, WAXED_OXIDIZED_COPPER,
WAXED_CUT_COPPER, WAXED_EXPOSED_CUT_COPPER, WAXED_WEATHERED_CUT_COPPER,
WAXED_OXIDIZED_CUT_COPPER, WAXED_CUT_COPPER_STAIRS, WAXED_EXPOSED_CUT_COPPER_STAIRS,
WAXED_WEATHERED_CUT_COPPER_STAIRS, WAXED_OXIDIZED_CUT_COPPER_STAIRS, WAXED_CUT_COPPER_SLAB,
WAXED_EXPOSED_CUT_COPPER_SLAB, WAXED_WEATHERED_CUT_COPPER_SLAB, WAXED_OXIDIZED_CUT_COPPER_SLAB ->
true;
default -> false;
};
// copied from the MaterialTags class in Paper
return type.name().startsWith("WAXED_") && type.name().contains("COPPER");
}
public static boolean isUnwaxedCopper(Material type) {
// copied from the MaterialTags class in Paper
return switch (type) {
case COPPER_BLOCK, EXPOSED_COPPER, WEATHERED_COPPER, OXIDIZED_COPPER, CUT_COPPER,
EXPOSED_CUT_COPPER, WEATHERED_CUT_COPPER, OXIDIZED_CUT_COPPER, CUT_COPPER_STAIRS,
EXPOSED_CUT_COPPER_STAIRS, WEATHERED_CUT_COPPER_STAIRS, OXIDIZED_CUT_COPPER_STAIRS,
CUT_COPPER_SLAB, EXPOSED_CUT_COPPER_SLAB, WEATHERED_CUT_COPPER_SLAB, OXIDIZED_CUT_COPPER_SLAB ->
true;
default -> false;
case COPPER_BLOCK, CHISELED_COPPER, COPPER_DOOR, COPPER_TRAPDOOR, COPPER_GRATE, COPPER_BULB -> true;
default -> type.name().startsWith("EXPOSED_") || type.name().startsWith("WEATHERED_") ||
type.name().startsWith("OXIDIZED_") || type.name().startsWith("CUT_COPPER");
};
}

View File

@ -3,4 +3,4 @@ main: com.sk89q.worldguard.bukkit.WorldGuardPlugin
version: "${internalVersion}"
depend: [WorldEdit]
softdepend: [CommandBook]
api-version: "1.20"
api-version: "1.21"

View File

@ -1,20 +1,51 @@
import org.cadixdev.gradle.licenser.LicenseExtension
plugins {
`java-library`
id("buildlogic.core-and-platform")
}
applyPlatformAndCoreConfiguration()
dependencies {
constraints {
"implementation"(libs.snakeyaml) {
because("Bukkit provides SnakeYaml")
}
}
"api"(project(":worldguard-libs:core"))
"api"("com.sk89q.worldedit:worldedit-core:${Versions.WORLDEDIT}")
"implementation"("org.flywaydb:flyway-core:3.0")
"implementation"("org.yaml:snakeyaml:2.0")
"implementation"("com.google.guava:guava:${Versions.GUAVA}")
"api"(libs.worldedit.core)
"implementation"(libs.flyway.core)
"implementation"(libs.snakeyaml)
"implementation"(libs.guava)
"compileOnlyApi"(libs.jsr305)
"implementation"(libs.gson)
"compileOnly"("com.google.code.findbugs:jsr305:${Versions.FINDBUGS}")
"testImplementation"("org.hamcrest:hamcrest-library:2.2")
"compileOnly"(libs.worldedit.libs.ap)
"annotationProcessor"(libs.worldedit.libs.ap)
// ensure this is on the classpath for the AP
"annotationProcessor"(libs.guava)
"compileOnly"(libs.autoService) {
because("Needed to resolve annotations in Piston")
}
tasks.withType<JavaCompile>().configureEach {
"testImplementation"(libs.hamcrest.library)
}
tasks.compileJava {
dependsOn(":worldguard-libs:build")
options.compilerArgs.add("-Aarg.name.key.prefix=")
}
configure<LicenseExtension> {
exclude {
it.file.startsWith(project.layout.buildDirectory.get().asFile)
}
}
configure<PublishingExtension> {
publications.named<MavenPublication>("maven") {
artifactId = the<BasePluginExtension>().archivesName.get()
from(components["java"])
}
}

View File

@ -70,7 +70,7 @@ public void god(CommandContext args, Actor sender) throws CommandException, Auth
// Keep track of this
included = true;
} else {
} else if (!args.hasFlag('s')) {
player.print("God enabled by " + sender.getDisplayName() + ".");
}
@ -79,7 +79,7 @@ public void god(CommandContext args, Actor sender) throws CommandException, Auth
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included && args.hasFlag('s')) {
if (!included) {
sender.print("Players now have god mode.");
}
}
@ -113,7 +113,7 @@ public void ungod(CommandContext args, Actor sender) throws CommandException, Au
// Keep track of this
included = true;
} else {
} else if (!args.hasFlag('s')) {
player.print("God disabled by " + sender.getDisplayName() + ".");
}
@ -122,7 +122,7 @@ public void ungod(CommandContext args, Actor sender) throws CommandException, Au
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included && args.hasFlag('s')) {
if (!included) {
sender.print("Players no longer have god mode.");
}
}
@ -158,7 +158,7 @@ public void heal(CommandContext args, Actor sender) throws CommandException, Aut
// Keep track of this
included = true;
} else {
} else if (!args.hasFlag('s')) {
player.print("Healed by " + sender.getDisplayName() + ".");
}
@ -166,7 +166,7 @@ public void heal(CommandContext args, Actor sender) throws CommandException, Aut
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included && args.hasFlag('s')) {
if (!included) {
sender.print("Players healed.");
}
}
@ -199,7 +199,7 @@ public void slay(CommandContext args, Actor sender) throws CommandException, Aut
// Keep track of this
included = true;
} else {
} else if (!args.hasFlag('s')) {
player.print("Slain by " + sender.getDisplayName() + ".");
}
@ -207,7 +207,7 @@ public void slay(CommandContext args, Actor sender) throws CommandException, Aut
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included && args.hasFlag('s')) {
if (!included) {
sender.print("Players slain.");
}
}

View File

@ -101,6 +101,7 @@ public abstract class WorldConfiguration {
public boolean blockEnderDragonPortalCreation;
public boolean blockFireballExplosions;
public boolean blockFireballBlockDamage;
public boolean blockWindChargeExplosions;
public boolean blockOtherExplosions;
public boolean blockEntityPaintingDestroy;
public boolean blockEntityItemFrameDestroy;
@ -166,6 +167,7 @@ public abstract class WorldConfiguration {
public boolean disableEndermanGriefing;
public boolean disableSnowmanTrails;
public boolean disableSoilDehydration;
public boolean disableSoilMoistureChange;
public boolean disableCoralBlockFade;
public boolean disableCopperBlockFade;
public Set<String> allowedSnowFallOver;

View File

@ -74,6 +74,7 @@ public final class Flags {
public static final StateFlag FIREWORK_DAMAGE = register(new StateFlag("firework-damage", false));
public static final StateFlag USE_ANVIL = register(new StateFlag("use-anvil", false));
public static final StateFlag USE_DRIPLEAF = register(new StateFlag("use-dripleaf", false));
public static final StateFlag WIND_CHARGE_BURST = register(new StateFlag("wind-charge-burst", false));
// These flags are similar to the ones above (used in tandem with BUILD),
// but their defaults are set to TRUE because it is more user friendly.
@ -93,6 +94,7 @@ public final class Flags {
public static final StateFlag ENDERDRAGON_BLOCK_DAMAGE = register(new StateFlag("enderdragon-block-damage", true));
public static final StateFlag GHAST_FIREBALL = register(new StateFlag("ghast-fireball", true));
public static final StateFlag OTHER_EXPLOSION = register(new StateFlag("other-explosion", true));
public static final StateFlag BREEZE_WIND_CHARGE = register(new StateFlag("breeze-charge-explosion", true));
public static final StateFlag WITHER_DAMAGE = register(new StateFlag("wither-damage", true));
public static final StateFlag ENDER_BUILD = register(new StateFlag("enderman-grief", true));
public static final StateFlag SNOWMAN_TRAILS = register(new StateFlag("snowman-trails", true));
@ -128,6 +130,7 @@ public final class Flags {
public static final StateFlag COPPER_FADE = register(new StateFlag("copper-fade", true));
public static final StateFlag WATER_FLOW = register(new StateFlag("water-flow", true));
public static final StateFlag LAVA_FLOW = register(new StateFlag("lava-flow", true));
public static final StateFlag MOISTURE_CHANGE = register(new StateFlag("moisture-change", true));
public static final RegistryFlag<WeatherType> WEATHER_LOCK = register(new RegistryFlag<>("weather-lock", WeatherType.REGISTRY));
public static final StringFlag TIME_LOCK = register(new StringFlag("time-lock"));

View File

@ -19,6 +19,7 @@
package com.sk89q.worldguard.session;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
@ -67,10 +68,9 @@ public abstract class AbstractSessionManager implements SessionManager {
.expireAfterWrite(2, TimeUnit.SECONDS)
.build(CacheLoader.from(tuple -> BYPASS_PERMISSION_TEST.test(tuple.getWorld(), tuple.getPlayer())));
private final LoadingCache<CacheKey, Session> sessions = CacheBuilder.newBuilder()
private final Cache<CacheKey, Session> sessions = CacheBuilder.newBuilder()
.expireAfterAccess(SESSION_LIFETIME, TimeUnit.MINUTES)
.build(CacheLoader.from(key ->
createSession(key.playerRef.get())));
.build();
private boolean hasCustom = false;
private List<Handler.Factory<? extends Handler>> handlers = new LinkedList<>();
@ -152,7 +152,7 @@ public boolean hasBypass(LocalPlayer player, World world) {
@Override
public void resetState(LocalPlayer player) {
checkNotNull(player, "player");
@Nullable Session session = sessions.getIfPresent(new CacheKey(player));
@Nullable Session session = getIfPresentInternal(new CacheKey(player));
if (session != null) {
session.resetState(player);
}
@ -161,22 +161,35 @@ public void resetState(LocalPlayer player) {
@Override
@Nullable
public Session getIfPresent(LocalPlayer player) {
return sessions.getIfPresent(new CacheKey(player));
return getIfPresentInternal(new CacheKey(player));
}
private Session getIfPresentInternal(CacheKey cacheKey) {
@Nullable Session session = sessions.getIfPresent(cacheKey);
if (session != null) {
session.ensureInitialized(cacheKey.playerRef.get(), this::initializeSession);
return session;
}
return null;
}
@Override
public Session get(LocalPlayer player) {
return sessions.getUnchecked(new CacheKey(player));
Session session = sessions.asMap().computeIfAbsent(new CacheKey(player), (k) -> new Session(this));
session.ensureInitialized(player, this::initializeSession);
return session;
}
@Override
public Session createSession(LocalPlayer player) {
Session session = new Session(this);
return get(player);
}
private void initializeSession(Session session, LocalPlayer player) {
for (Handler.Factory<? extends Handler> factory : handlers) {
session.register(factory.create(session));
}
session.initialize(player);
return session;
}
protected static final class CacheKey {

View File

@ -38,6 +38,7 @@
import java.util.HashMap;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.BiConsumer;
import static com.google.common.base.Preconditions.checkNotNull;
@ -52,6 +53,7 @@ public class Session {
private Location lastValid;
private Set<ProtectedRegion> lastRegionSet;
private final AtomicBoolean needRefresh = new AtomicBoolean(false);
private boolean initialized;
/**
* Create a new session.
@ -120,6 +122,14 @@ public void initialize(LocalPlayer player) {
}
}
synchronized void ensureInitialized(LocalPlayer player, BiConsumer<Session, LocalPlayer> initializer) {
if (initialized) {
return;
}
initialized = true;
initializer.accept(this, player);
}
/**
* Uninitialize the session.
*

View File

@ -95,7 +95,9 @@ public interface SessionManager {
*
* @param player The player
* @return The new session
* @deprecated Use {@link SessionManager#get} instead
*/
@Deprecated
Session createSession(LocalPlayer player);
/**

View File

@ -1,2 +0,0 @@
applyLibrariesConfiguration()
constrainDependenciesToLibsCore()

View File

@ -1,18 +1,10 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
applyLibrariesConfiguration()
plugins {
id("buildlogic.libs")
}
dependencies {
"shade"("org.enginehub:squirrelid:${Versions.SQUIRRELID}")
"shade"("org.khelekore:prtree:1.5.0")
}
tasks.named<ShadowJar>("jar") {
dependencies {
relocate("org.enginehub.squirrelid", "com.sk89q.worldguard.util.profile") {
include(dependency("org.enginehub:squirrelid"))
}
include(dependency("org.khelekore:prtree"))
"shade"(libs.squirrelid) {
isTransitive = false
}
"shade"(libs.prtree)
}